Upcoming SlideShare
×

# A Developers Guide to Encryption

1,989

Published on

2 Likes
Statistics
Notes
• Full Name
Comment goes here.

Are you sure you want to Yes No
• Be the first to comment

Views
Total Views
1,989
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
46
0
Likes
2
Embeds 0
No embeds

No notes for slide

### A Developers Guide to Encryption

1. 1. A Developer’s Guide to Encryption<br />Barry Dorrans<br />MVP – Developer Security<br />(well for 9 more days anyway)barryd@idunno.org<br />
2. 2. A Developer’s Guide to Encryption<br />What is cryptography?<br />Random Numbers<br />Hashing<br />Symmetric Encryption<br />Deriving keys from passwords<br />Asymmetric Encryption<br />Manual Asymmetric Encryption<br />X509 Certificates<br />Message Authentication Codes<br />Encrypting and Signing XML<br />
3. 3. What is cryptography?<br />This session will not include mathematics.<br />Cryptography - the study of techniques and applications that depend on the existence of difficult problems. <br />Cryptanalysis - the study of how to compromise (defeat) cryptographic mechanisms.<br />Cryptology - (from the Greek “kryptóslógos” meaning “hidden word”) is the discipline of cryptography and cryptanalysis combined.<br />
4. 4. Definitions<br />Plaintext / Cleartext – Unencrypted Data.<br />Ciphertext –Encrypted Data.<br />Cipher –Encryption algorithm.<br />
5. 5. Random Numbers<br />Cryptography needs random numbers.<br />Random isn’t really random.<br />PRNG – Pseudo Random Number Generator.<br />xn+1=aXn+bmod m <br /> <br />
6. 6. Cryptographically Secure Random Numbers<br />System.Security.Cryptography.RandomNumberGenerator<br />public static byte[] GenerateRandomBytes(intlength)<br />{<br /> byte[] randomArray = new byte[length];<br />RNGCryptoServiceProviderrng = new RNGCryptoServiceProvider();<br />rng.GetBytes(randomArray);<br /> return randomArray;<br />}<br />
7. 7. Hardware RNGs<br />Based on<br />Radioactive decay,<br />Background noise,<br />Other entropy source.<br />Specialised Hardware.<br />But now even Intel Chipsets have hardware RNGs.<br />(Post Office Ernie)<br />
8. 8. Hashing<br />A well-defined procedure or mathematical function that converts a large, possibly variable-sized amount of data into a small datum.<br />One way.<br />Typically used for passwords, checksums.<br />
9. 9. Generating a hash<br />HashAlgorithmalgorithm = new SHA256Managed();<br />byte[] hash = algorithm.ComputeHash(plaintext);<br />
10. 10. Hash Algorithms<br />MD Family (MD2, MD4, MD5)<br />SHA Family (SHA1, SHA2, SHA3)<br />Whirlpool<br />MD*, SHA1 are no longer considered secure<br />SHA2 are the most commonly used<br />Whirlpool is the newest ISO standard.No implementation in the .NET framework.<br />
11. 11. Salting the hash<br />Salting adds a random piece of data to the plaintext.<br />Stops pre-computed lookups and rainbow tables.<br />Never hash without salt.<br />Salts can be stored beside the hash.<br />
12. 12. Salting a hash<br />HashAlgorithmalgorithm = new SHA256Managed();<br />byte[] plainTextWithSaltBytes = <br /> new byte[plainText.Length + salt.Length];<br />for (int i = 0; i < plainText.Length; i++)<br />{<br />plainTextWithSaltBytes[i] = plainText[i];<br />}<br />for (int i = 0; i < salt.Length; i++)<br />{<br />plainTextWithSaltBytes[plainText.Length+ i] = salt[i];<br />}<br />byte[] hash =algorithm.ComputeHash(plainTextWithSaltBytes); <br />
13. 13. Comparing byte arrays<br />public static bool CompareByteArrays( byte[] array1, byte[] array2)<br />{<br /> if (array1.Length != array2.Length)<br /> return false;<br /> for (int i = 0; i < array1.Length; i++)<br />{<br /> if (array1[i] != array2[i])<br /> return false;<br /> }<br /> return true;<br />}<br />
14. 14. Demo Time!<br />
15. 15. Encryption Keys<br />Once you lose them change the “locks”.<br />Keys are like condoms -<br />don’t reuse them.<br />
16. 16. Symmetric Encryption<br />A single key is used for encryption and decryption.<br />Fast, computationally cheap.<br />Needs a shared key.<br />Repudiable.<br />
17. 17. Symmetric Keys<br />Keys are cryptographically secure random data.<br />Size of key depends on algorithm.<br />
18. 18. Initialization Vectors<br />Symmetric algorithms tend to be block algorithms.<br />The result of a block encryption feeds into the next block.<br />An IV is the initial starting block.<br />An IV is cryptographically secure random data<br />
19. 19. Demo Time!<br />
20. 20. Encrypting Symmetrically<br />RijndaelManagedrijndaelManaged = new RijndaelManaged();<br />ICryptoTransformcryptoTransform = rijndaelManaged.CreateEncryptor(<br /> key, <br /> IV);<br />MemoryStreamoutputStream = new MemoryStream();<br />CryptoStreamcryptoStream = new CryptoStream(<br />outputStream,<br />cryptoTransform,<br />CryptoStreamMode.Write);<br />cryptoStream.Write(plaintextAsBytes, 0,plaintextAsBytes.Length);<br />cryptoStream.FlushFinalBlock();<br />byte[] ciphertextAsBytes = outputStream.ToArray();<br />
21. 21. Decrypting Symmetrically<br />RijndaelManagedrijndaelManaged = new RijndaelManaged();<br />ICryptoTransformcryptoTransform = rijndaelManaged.CreateDecryptor(<br /> key, <br /> IV);<br />MemoryStreamoutputStream = new MemoryStream();<br />CryptoStreamcryptoStream = new CryptoStream(<br />outputStream,<br />cryptoTransform,<br />CryptoStreamMode.Write);<br />cryptoStream.Write(plaintextAsBytes, 0,plaintextAsBytes.Length);<br />cryptoStream.FlushFinalBlock();<br />byte[] ciphertextAsBytes = outputStream.ToArray();<br />
22. 22. Symmetric Encryption Algorithms<br />DES<br />TripleDES<br />Rivest Cipher 2<br />Rijndael/AES<br />DES/RC considered unsafe.<br />Rijndael is the most commonly used.<br />
23. 23. Deriving keys from passwords<br />RFC2898 derives a key and IV from a password and a salt<br />private static void GetKeyAndIVFromPasswordAndSalt(<br /> string password, byte[] salt,<br />SymmetricAlgorithmsymmetricAlgorithm,<br /> ref byte[] key, ref byte[] iv)<br />{<br /> Rfc2898DeriveBytes rfc2898DeriveBytes =<br /> new Rfc2898DeriveBytes(password, salt);<br /> key =<br /> rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.KeySize/ 8);<br /> iv =<br /> rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.BlockSize/ 8);<br />}<br />
24. 24. Message Authentication Codes<br />MACs provide data integrity.<br />A checksum of the plaintext combined with a MAC key.<br />MAC can be stored alongside data, key cannot.<br />
25. 25. Demo Time!<br />
26. 26. Generating a MAC<br />private static byte[] CalculateMAC( byte[] plainText, byte[] key)<br />{<br /> HMACSHA256 hmac = new HMACSHA256(key);<br /> return hmac.ComputeHash(plainText);<br />}<br />
27. 27. Asymmetric Encryption<br />Two keys are used.<br />A public key allows encryption.<br />A private key allows decryption.<br />Slow, computationally heavy.<br />Only for small amounts of data.<br />
28. 28. Demo Time!<br />
29. 29. Encrypting Asymmetrically<br />RSACryptoServiceProviderrsa = new RSACryptoServiceProvider(1024);<br />string publicKey =rsa.ToXmlString(false);<br />string privateKey=rsa.ToXmlString(true);<br />…<br />RSACryptoServiceProviderrsa= new RSACryptoServiceProvider(); rsa.FromXmlString(publicKey);<br />byte[] ciphertextAsBytes = rsa.Encrypt(plaintextAsBytes, true);<br />
30. 30. Encrypting Asymmetrically<br />RSACryptoServiceProviderrsa = new RSACryptoServiceProvider(1024);<br />string publicKey =rsa.ToXmlString(false);<br />string privateKey=rsa.ToXmlString(true);<br />…<br />RSACryptoServiceProviderrsa= new RSACryptoServiceProvider(); rsa.FromXmlString(privateKey);<br />byte[] plaintextAsBytes= rsa.Decrypt(ciphertextAsBytes, true);<br />
31. 31. X509 Certificate Encryption<br />Certificates are a container for a public and private key.<br />HTTPS certificate properties show the public key.<br />Windows has a secure certificate store.<br />Private keys have ACLs.Allow access via Certificate MMC snap-in<br />
32. 32. Demo Time!<br />
33. 33. Making Certificates with makecert<br />makecert -svdevReedRootCA.pvk -r -n "CN=Development Root CA" devRootCA.cer<br />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 <br />pvk2pfx -pvkbarryd.pvk-spcbarryd.cer -pfxbarryd.pfx<br />
34. 34. Loading a Certificate<br />static X509Certificate2 LoadCertificate(string serialNumber)<br />{<br /> X509Store certificateStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);<br />certificateStore.Open(OpenFlags.ReadOnly);<br /> X509Certificate2Collection searchResults =<br />certificateStore.Certificates.Find(<br /> X509FindType.FindBySerialNumber,<br />serialNumber,<br /> false);<br /> if (searchResults.Count != 1)<br />{<br /> throw new ArgumentException(<br /> "Cannot find individual certificate with the serial # specified.", "serialNumber");<br />}<br />certificateStore.Close();<br /> return searchResults[0];<br />}<br />
35. 35. Encrypting With A Certificate<br />X509Certificate2 certificate = LoadCertificate(this.serialNumber.Text);<br />RSACryptoServiceProviderencryptionProvider = (RSACryptoServiceProvider)certificate.PublicKey.Key;<br />byte[] cipherText= encryptionProvider.Encrypt(plaintextAsBytes, true));<br />
36. 36. Decrypting With A Certificate<br />X509Certificate2 certificate = LoadCertificate(this.serialNumber.Text);<br />if (!certificate.HasPrivateKey)<br /> throw new CryptographicException(<br /> "No private key.");<br />RSACryptoServiceProviderencryptionProvider = (RSACryptoServiceProvider)certificate;<br />byte[] plaintext = encryptionProvider.Decrypt(ciphertextAsBytes, true));<br />
37. 37. Envelopes & Signing with certificates<br />Signing guarantees data integrity.<br />Signing with a certificate provides non-repudiation.<br />CMS / PKCS #7 is the standard envelope format.<br />
38. 38. Encrypting a CMS envelope<br />static byte[] EncryptForCertificate( byte[] plaintext, X509Certificate2 certificate)<br />{<br />ContentInfocontentInfo = new ContentInfo(plaintext);<br />EnvelopedCmsenvelopedCms = new EnvelopedCms(contentInfo);<br />CmsRecipientrecipient = new CmsRecipient(certificate);<br />envelopedCms.Encrypt(recipient);<br />return envelopedCms.Encode();<br />}<br />
39. 39. Signing a CMS envelope<br />static byte[] SignWithCertificate(<br /> byte[] plaintext,<br /> X509Certificate2 certificate)<br />{<br />ContentInfocontentInfo = new ContentInfo(plaintext);<br />CmsSigner signer = <br /> new CmsSigner(certificate);<br />SignedCmssignedCms = <br /> new SignedCms(contentInfo);<br />signedCms.ComputeSignature(signer);<br /> return signedCms.Encode();<br />}<br />
40. 40. Decrypting a CMS envelope<br />static byte[] DecryptEnvelopedCMS(<br /> byte[] envelopeAsBytes)<br />{<br />EnvelopedCmsenvelopedCms = <br /> new EnvelopedCms();<br />envelopedCms.Decode(envelopeAsBytes);<br />envelopedCms.Decrypt();<br /> return envelopedCms.ContentInfo.Content;<br />}<br />
41. 41. Validating X509 Signatures<br />static bool IsSignatureValid(SignedCmssignedCms)<br />{<br /> bool result = false;<br /> try<br /> {<br /> // Call with true to check CRLs.<br />signedCms.CheckSignature(false);<br />foreach (SignerInfosignerInfo in signedMessage.SignerInfos)<br /> {<br /> X509Certificate2 signingCert = signerInfo.Certificate;<br /> // Validate signingCert is known.<br /> }<br /> result = true;<br /> }<br /> catch (CryptographicException)<br /> {<br /> }<br /> return result;<br />}<br />
42. 42. Encrypting and Signing XML<br />XML has standards for Encryption and Signing - XmlEnc & XmlDSig<br />Can encrypt and sign multiple elements with multiple keys.<br />Typically done with certificates.<br />Certificate is used to protect generated symmetric key.<br />
43. 43. Demo Time!<br />
44. 44. Encrypting XML<br />private static void EncryptXml(<br />XmlDocument document,<br /> string elementIdToEncrypt,<br /> X509Certificate2 certificate)<br />{<br /> // Extract the element to encrypt<br />XmlElementelementToEncrypt = document.GetElementsByTagName(elementIdToEncrypt)[0] as XmlElement;<br /> if (elementToEncrypt == null)<br /> {<br /> throw new XmlException("The specified element was not found");<br /> }<br /> // Create an instance of the encryptedXml class,<br /> // and encrypt the data<br />EncryptedXmlencryptedXml = new EncryptedXml();<br />EncryptedDataencryptedData = encryptedXml.Encrypt(elementToEncrypt, certificate);<br /> // Replace the original element.<br />EncryptedXml.ReplaceElement(elementToEncrypt, encryptedData, false);<br />}<br />
45. 45. Decrypting XML<br />private static void DecryptXml(XmlDocumentdocument)<br />{<br /> // Create a new EncryptedXml object // from the document<br />EncryptedXmlencryptedXml = new EncryptedXml(document);<br /> // Decrypt the document.<br />encryptedXml.DecryptDocument();<br />}<br />
46. 46. Signing XML<br />private static void SignXml(XmlDocument document, X509Certificate2 certificate)<br />{<br />SignedXmlsignedXml = new SignedXml(document) {SigningKey= certificate.PrivateKey}; <br /> Reference reference = new Reference { Uri = string.Empty};<br /> XmlDsigC14NTransform transform = new XmlDsigC14NTransform();<br />reference.AddTransform(transform);<br />XmlDsigEnvelopedSignatureTransformenvelope = new XmlDsigEnvelopedSignatureTransform();<br />reference.AddTransform(envelope);<br />signedXml.AddReference(reference);<br />KeyInfokeyInfo = new KeyInfo();<br />keyInfo.AddClause(new KeyInfoX509Data(certificate));<br />signedXml.KeyInfo = keyInfo;<br />signedXml.ComputeSignature();<br />XmlElementxmlDigitalSignature = signedXml.GetXml();<br />document.DocumentElement.AppendChild(document.ImportNode(xmlDigitalSignature, true));<br />}<br />
47. 47. Validating XML Signatures<br />private static bool VerifySignature(XmlDocument document)<br />{<br />SignedXmlsignedXml = new SignedXml(document);<br />XmlNodeListnodeList = document.GetElementsByTagName("Signature");<br /> if (nodeList.Count <= 0)<br /> {<br /> throw new CryptographicException("No signature found.");<br /> }<br />signedXml.LoadXml((XmlElement)nodeList[0]);<br /> return signedXml.CheckSignature();<br />}<br />
48. 48. Extracting the signing certificate<br />private static bool VerifySignature(XmlDocument document, out X509Certificate signingCertificate)<br />{<br />SignedXmlsignedXml = new SignedXml(document);<br />XmlNodeListnodeList = document.GetElementsByTagName("Signature");<br /> if (nodeList.Count <= 0)<br /> throw new CryptographicException("No signature found.");<br />signedXml.LoadXml((XmlElement)nodeList[0]);<br />signingCertificate = null;<br />foreach(KeyInfoClausekeyInfoClause in signedXml.KeyInfo)<br /> {<br /> if (!(keyInfoClause is KeyInfoX509Data))<br /> continue;<br /> KeyInfoX509Data keyInfoX509Data = keyInfoClause as KeyInfoX509Data;<br /> if ((keyInfoX509Data.Certificates != null) && (keyInfoX509Data.Certificates.Count == 1))<br />signingCertificate= (X509Certificate)keyInfoX509Data.Certificates[0];<br /> } <br /> return signedXml.CheckSignature();<br />}<br />
49. 49. Links<br />http://www.keylength.com/ - collection of recommended algorithms, key lengths and expiries.<br />http://csrc.nist.gov/groups/ST/toolkit/ - US National Institute of Standards and Technology recommendations<br />
50. 50. Buy my book<br />Beginning ASP.NET Security<br />Wrox Press<br />ISBN: 978-0470743652<br />Available now!<br />An ideal valentine’s gift for your loved one …<br />
1. #### A particular slide catching your eye?

Clipping is a handy way to collect important slides you want to go back to later.