1 / 50

A Developer’s Guide to Encryption

A Developer’s Guide to Encryption. Barry Dorrans MVP – Developer Security (well for 9 more days anyway) barryd@idunno.org. A Developer’s Guide to Encryption. What is cryptography? Random Numbers Hashing Symmetric Encryption Deriving keys from passwords Asymmetric Encryption

arleen
Download Presentation

A Developer’s Guide to Encryption

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. A Developer’s Guide to Encryption Barry Dorrans MVP – Developer Security (well for 9 more days anyway)barryd@idunno.org

  2. A Developer’s Guide to Encryption • What is cryptography? • Random Numbers • Hashing • Symmetric Encryption • Deriving keys from passwords • Asymmetric Encryption • Manual Asymmetric Encryption • X509 Certificates • Message Authentication Codes • Encrypting and Signing XML

  3. What is cryptography? • This session will not include mathematics. • Cryptography - the study of techniques and applications that depend on the existence of difficult problems. • Cryptanalysis - the study of how to compromise (defeat) cryptographic mechanisms. • Cryptology - (from the Greek “kryptóslógos” meaning “hidden word”) is the discipline of cryptography and cryptanalysis combined.

  4. Definitions • Plaintext / Cleartext – Unencrypted Data. • Ciphertext –Encrypted Data. • Cipher –Encryption algorithm.

  5. Random Numbers • Cryptography needs random numbers. • Random isn’t really random. • PRNG – Pseudo Random Number Generator.

  6. Cryptographically Secure Random Numbers • System.Security.Cryptography.RandomNumberGenerator public static byte[] GenerateRandomBytes(intlength) { byte[] randomArray = new byte[length]; RNGCryptoServiceProviderrng = new RNGCryptoServiceProvider(); rng.GetBytes(randomArray); return randomArray; }

  7. Hardware RNGs • Based on • Radioactive decay, • Background noise, • Other entropy source. • Specialised Hardware. • But now even Intel Chipsets have hardware RNGs. • (Post Office Ernie)

  8. Hashing • A well-defined procedure or mathematical function that converts a large, possibly variable-sized amount of data into a small datum. • One way. • Typically used for passwords, checksums.

  9. Generating a hash HashAlgorithmalgorithm = new SHA256Managed(); byte[] hash = algorithm.ComputeHash(plaintext);

  10. Hash Algorithms • MD Family (MD2, MD4, MD5) • SHA Family (SHA1, SHA2, SHA3) • Whirlpool • MD*, SHA1 are no longer considered secure • SHA2 are the most commonly used • Whirlpool is the newest ISO standard.No implementation in the .NET framework.

  11. Salting the hash • Salting adds a random piece of data to the plaintext. • Stops pre-computed lookups and rainbow tables. • Never hash without salt. • Salts can be stored beside the hash.

  12. Salting a hash HashAlgorithmalgorithm = new SHA256Managed(); byte[] plainTextWithSaltBytes = new byte[plainText.Length + salt.Length]; for (int i = 0; i < plainText.Length; i++) { plainTextWithSaltBytes[i] = plainText[i]; } for (int i = 0; i < salt.Length; i++) { plainTextWithSaltBytes[plainText.Length+ i] = salt[i]; } byte[] hash =algorithm.ComputeHash(plainTextWithSaltBytes);

  13. Comparing byte arrays public static bool CompareByteArrays( byte[] array1, byte[] array2) { if (array1.Length != array2.Length) return false; for (int i = 0; i < array1.Length; i++) { if (array1[i] != array2[i]) return false; } return true; }

  14. Demo Time!

  15. Encryption Keys • Once you lose them change the “locks”. • Keys are like condoms - don’t reuse them.

  16. Symmetric Encryption • A single key is used for encryption and decryption. • Fast, computationally cheap. • Needs a shared key. • Repudiable.

  17. Symmetric Keys • Keys are cryptographically secure random data. • Size of key depends on algorithm.

  18. Initialization Vectors • Symmetric algorithms tend to be block algorithms. • The result of a block encryption feeds into the next block. • An IV is the initial starting block. • An IV is cryptographically secure random data

  19. Demo Time!

  20. Encrypting Symmetrically RijndaelManagedrijndaelManaged = new RijndaelManaged(); ICryptoTransformcryptoTransform = rijndaelManaged.CreateEncryptor( key, IV); MemoryStreamoutputStream = new MemoryStream(); CryptoStreamcryptoStream = new CryptoStream( outputStream, cryptoTransform, CryptoStreamMode.Write); cryptoStream.Write(plaintextAsBytes, 0,plaintextAsBytes.Length); cryptoStream.FlushFinalBlock(); byte[] ciphertextAsBytes = outputStream.ToArray();

  21. Decrypting Symmetrically RijndaelManagedrijndaelManaged = new RijndaelManaged(); ICryptoTransformcryptoTransform = rijndaelManaged.CreateDecryptor( key, IV); MemoryStreamoutputStream = new MemoryStream(); CryptoStreamcryptoStream = new CryptoStream( outputStream, cryptoTransform, CryptoStreamMode.Write); cryptoStream.Write(plaintextAsBytes, 0,plaintextAsBytes.Length); cryptoStream.FlushFinalBlock(); byte[] ciphertextAsBytes = outputStream.ToArray();

  22. Symmetric Encryption Algorithms • DES • TripleDES • Rivest Cipher 2 • Rijndael/AES • DES/RC considered unsafe. • Rijndael is the most commonly used.

  23. Deriving keys from passwords • RFC2898 derives a key and IV from a password and a salt private static void GetKeyAndIVFromPasswordAndSalt( string password, byte[] salt, SymmetricAlgorithmsymmetricAlgorithm, ref byte[] key, ref byte[] iv) { Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt); key = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.KeySize/ 8); iv = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.BlockSize/ 8); }

  24. Message Authentication Codes • MACs provide data integrity. • A checksum of the plaintext combined with a MAC key. • MAC can be stored alongside data, key cannot.

  25. Demo Time!

  26. Generating a MAC private static byte[] CalculateMAC( byte[] plainText, byte[] key) { HMACSHA256 hmac = new HMACSHA256(key); return hmac.ComputeHash(plainText); }

  27. Asymmetric Encryption • Two keys are used. • A public key allows encryption. • A private key allows decryption. • Slow, computationally heavy. • Only for small amounts of data.

  28. Demo Time!

  29. Encrypting Asymmetrically RSACryptoServiceProviderrsa = new RSACryptoServiceProvider(1024); string publicKey =rsa.ToXmlString(false); string privateKey=rsa.ToXmlString(true); … RSACryptoServiceProviderrsa= new RSACryptoServiceProvider(); rsa.FromXmlString(publicKey); byte[] ciphertextAsBytes = rsa.Encrypt(plaintextAsBytes, true);

  30. Encrypting Asymmetrically RSACryptoServiceProviderrsa = new RSACryptoServiceProvider(1024); string publicKey =rsa.ToXmlString(false); string privateKey=rsa.ToXmlString(true); … RSACryptoServiceProviderrsa= new RSACryptoServiceProvider(); rsa.FromXmlString(privateKey); byte[] plaintextAsBytes= rsa.Decrypt(ciphertextAsBytes, true);

  31. X509 Certificate Encryption • Certificates are a container for a public and private key. • HTTPS certificate properties show the public key. • Windows has a secure certificate store. • Private keys have ACLs.Allow access via Certificate MMC snap-in

  32. Demo Time!

  33. Making Certificates with makecert makecert -svdevReedRootCA.pvk -r -n "CN=Development Root CA" devRootCA.cer makecert -pe -n "CN=barryd" -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -ic devReedRootCA.cer -iv devRootCA.pvk-sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 -svbarryd.pvk barryd.cer pvk2pfx -pvkbarryd.pvk-spcbarryd.cer -pfxbarryd.pfx

  34. Loading a Certificate static X509Certificate2 LoadCertificate(string serialNumber) { X509Store certificateStore = new X509Store(StoreName.My, StoreLocation.CurrentUser); certificateStore.Open(OpenFlags.ReadOnly); X509Certificate2Collection searchResults = certificateStore.Certificates.Find( X509FindType.FindBySerialNumber, serialNumber, false); if (searchResults.Count != 1) { throw new ArgumentException( "Cannot find individual certificate with the serial # specified.", "serialNumber"); } certificateStore.Close(); return searchResults[0]; }

  35. Encrypting With A Certificate X509Certificate2 certificate = LoadCertificate(this.serialNumber.Text); RSACryptoServiceProviderencryptionProvider = (RSACryptoServiceProvider)certificate.PublicKey.Key; byte[] cipherText= encryptionProvider.Encrypt(plaintextAsBytes, true));

  36. Decrypting With A Certificate X509Certificate2 certificate = LoadCertificate(this.serialNumber.Text); if (!certificate.HasPrivateKey) throw new CryptographicException( "No private key."); RSACryptoServiceProviderencryptionProvider = (RSACryptoServiceProvider)certificate; byte[] plaintext = encryptionProvider.Decrypt(ciphertextAsBytes, true));

  37. Envelopes & Signing with certificates • Signing guarantees data integrity. • Signing with a certificate provides non-repudiation. • CMS / PKCS #7 is the standard envelope format.

  38. Encrypting a CMS envelope static byte[] EncryptForCertificate( byte[] plaintext, X509Certificate2 certificate) { ContentInfocontentInfo = new ContentInfo(plaintext); EnvelopedCmsenvelopedCms = new EnvelopedCms(contentInfo); CmsRecipientrecipient = new CmsRecipient(certificate); envelopedCms.Encrypt(recipient); return envelopedCms.Encode(); }

  39. Signing a CMS envelope static byte[] SignWithCertificate( byte[] plaintext, X509Certificate2 certificate) { ContentInfocontentInfo = new ContentInfo(plaintext); CmsSigner signer = new CmsSigner(certificate); SignedCmssignedCms = new SignedCms(contentInfo); signedCms.ComputeSignature(signer); return signedCms.Encode(); }

  40. Decrypting a CMS envelope static byte[] DecryptEnvelopedCMS( byte[] envelopeAsBytes) { EnvelopedCmsenvelopedCms = new EnvelopedCms(); envelopedCms.Decode(envelopeAsBytes); envelopedCms.Decrypt(); return envelopedCms.ContentInfo.Content; }

  41. Validating X509 Signatures static bool IsSignatureValid(SignedCmssignedCms) { bool result = false; try { // Call with true to check CRLs. signedCms.CheckSignature(false); foreach (SignerInfosignerInfo in signedMessage.SignerInfos) { X509Certificate2 signingCert = signerInfo.Certificate; // Validate signingCert is known. } result = true; } catch (CryptographicException) { } return result; }

  42. Encrypting and Signing XML • XML has standards for Encryption and Signing - XmlEnc & XmlDSig • Can encrypt and sign multiple elements with multiple keys. • Typically done with certificates. • Certificate is used to protect generated symmetric key.

  43. Demo Time!

  44. Encrypting XML private static void EncryptXml( XmlDocument document, string elementIdToEncrypt, X509Certificate2 certificate) { // Extract the element to encrypt XmlElementelementToEncrypt = document.GetElementsByTagName(elementIdToEncrypt)[0] as XmlElement; if (elementToEncrypt == null) { throw new XmlException("The specified element was not found"); } // Create an instance of the encryptedXml class, // and encrypt the data EncryptedXmlencryptedXml = new EncryptedXml(); EncryptedDataencryptedData = encryptedXml.Encrypt(elementToEncrypt, certificate); // Replace the original element. EncryptedXml.ReplaceElement(elementToEncrypt, encryptedData, false); }

  45. Decrypting XML private static void DecryptXml(XmlDocumentdocument) { // Create a new EncryptedXml object // from the document EncryptedXmlencryptedXml = new EncryptedXml(document); // Decrypt the document. encryptedXml.DecryptDocument(); }

  46. Signing XML private static void SignXml(XmlDocument document, X509Certificate2 certificate) { SignedXmlsignedXml = new SignedXml(document) {SigningKey= certificate.PrivateKey}; Reference reference = new Reference { Uri = string.Empty}; XmlDsigC14NTransform transform = new XmlDsigC14NTransform(); reference.AddTransform(transform); XmlDsigEnvelopedSignatureTransformenvelope = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(envelope); signedXml.AddReference(reference); KeyInfokeyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(certificate)); signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); XmlElementxmlDigitalSignature = signedXml.GetXml(); document.DocumentElement.AppendChild(document.ImportNode(xmlDigitalSignature, true)); }

  47. Validating XML Signatures private static bool VerifySignature(XmlDocument document) { SignedXmlsignedXml = new SignedXml(document); XmlNodeListnodeList = document.GetElementsByTagName("Signature"); if (nodeList.Count <= 0) { throw new CryptographicException("No signature found."); } signedXml.LoadXml((XmlElement)nodeList[0]); return signedXml.CheckSignature(); }

  48. Extracting the signing certificate private static bool VerifySignature(XmlDocument document, out X509Certificate signingCertificate) { SignedXmlsignedXml = new SignedXml(document); XmlNodeListnodeList = document.GetElementsByTagName("Signature"); if (nodeList.Count <= 0) throw new CryptographicException("No signature found."); signedXml.LoadXml((XmlElement)nodeList[0]); signingCertificate = null; foreach(KeyInfoClausekeyInfoClause in signedXml.KeyInfo) { if (!(keyInfoClause is KeyInfoX509Data)) continue; KeyInfoX509Data keyInfoX509Data = keyInfoClause as KeyInfoX509Data; if ((keyInfoX509Data.Certificates != null) && (keyInfoX509Data.Certificates.Count == 1)) signingCertificate= (X509Certificate)keyInfoX509Data.Certificates[0]; } return signedXml.CheckSignature(); }

  49. Links • http://www.keylength.com/ - collection of recommended algorithms, key lengths and expiries. • http://csrc.nist.gov/groups/ST/toolkit/ - US National Institute of Standards and Technology recommendations

  50. Buy my book Beginning ASP.NET Security Wrox Press ISBN: 978-0470743652 Available now! An ideal valentine’s gift for your loved one …

More Related