A Developer’s Guide to Encryption<br />Barry Dorrans<br />MVP – Developer Security<br />(well for 9 more days anyway)barry...
A Developer’s Guide to Encryption<br />What is cryptography?<br />Random Numbers<br />Hashing<br />Symmetric Encryption<br...
What is cryptography?<br />This session will not include mathematics.<br />Cryptography - the study of techniques and appl...
Definitions<br />Plaintext / Cleartext – Unencrypted Data.<br />Ciphertext –Encrypted Data.<br />Cipher –Encryption algori...
Random Numbers<br />Cryptography needs random numbers.<br />Random isn’t really random.<br />PRNG – Pseudo Random Number G...
Cryptographically Secure Random Numbers<br />System.Security.Cryptography.RandomNumberGenerator<br />public static byte[] ...
Hardware RNGs<br />Based on<br />Radioactive decay,<br />Background noise,<br />Other entropy source.<br />Specialised Har...
Hashing<br />A well-defined procedure or mathematical function that converts a large, possibly variable-sized amount of da...
Generating a hash<br />HashAlgorithmalgorithm =   new SHA256Managed();<br />byte[] hash = algorithm.ComputeHash(plaintext)...
Hash Algorithms<br />MD Family (MD2, MD4, MD5)<br />SHA Family  (SHA1, SHA2, SHA3)<br />Whirlpool<br />MD*, SHA1 are no lo...
Salting the hash<br />Salting adds a random piece of data to the plaintext.<br />Stops pre-computed lookups and rainbow ta...
Salting a hash<br />HashAlgorithmalgorithm = new SHA256Managed();<br />byte[] plainTextWithSaltBytes = <br />   new byte[p...
Comparing byte arrays<br />public static bool CompareByteArrays(    byte[] array1,     byte[] array2)<br />{<br />    if (...
Demo Time!<br />
Encryption Keys<br />Once you lose them change the “locks”.<br />Keys are like condoms -<br />don’t reuse them.<br />
Symmetric Encryption<br />A single key is used for encryption and decryption.<br />Fast, computationally cheap.<br />Needs...
Symmetric Keys<br />Keys are cryptographically secure random data.<br />Size of key depends on algorithm.<br />
Initialization Vectors<br />Symmetric algorithms tend to be block algorithms.<br />The result of a block encryption feeds ...
Demo Time!<br />
Encrypting Symmetrically<br />RijndaelManagedrijndaelManaged = new RijndaelManaged();<br />ICryptoTransformcryptoTransform...
Decrypting Symmetrically<br />RijndaelManagedrijndaelManaged = new RijndaelManaged();<br />ICryptoTransformcryptoTransform...
Symmetric Encryption Algorithms<br />DES<br />TripleDES<br />Rivest Cipher 2<br />Rijndael/AES<br />DES/RC considered unsa...
Deriving keys from passwords<br />RFC2898 derives a key and IV from a password and a salt<br />private static void GetKeyA...
Message Authentication Codes<br />MACs provide data integrity.<br />A checksum of the plaintext combined with a MAC key.<b...
Demo Time!<br />
Generating a MAC<br />private static byte[] CalculateMAC(    byte[] plainText,     byte[] key)<br />{<br />    HMACSHA256 ...
Asymmetric Encryption<br />Two keys are used.<br />A public key allows encryption.<br />A private key allows decryption.<b...
Demo Time!<br />
Encrypting Asymmetrically<br />RSACryptoServiceProviderrsa  = new RSACryptoServiceProvider(1024);<br />string publicKey =r...
Encrypting Asymmetrically<br />RSACryptoServiceProviderrsa  = new RSACryptoServiceProvider(1024);<br />string publicKey =r...
X509 Certificate Encryption<br />Certificates are a container for a public and private key.<br />HTTPS certificate propert...
Demo Time!<br />
Making Certificates with makecert<br />makecert -svdevReedRootCA.pvk -r -n "CN=Development Root CA" devRootCA.cer<br />mak...
Loading a Certificate<br />static X509Certificate2 LoadCertificate(string serialNumber)<br />{<br />   X509Store certifica...
Encrypting  With A Certificate<br />X509Certificate2 certificate = LoadCertificate(this.serialNumber.Text);<br />RSACrypto...
Decrypting  With A Certificate<br />X509Certificate2 certificate = LoadCertificate(this.serialNumber.Text);<br />if (!cert...
Envelopes & Signing with certificates<br />Signing guarantees data integrity.<br />Signing with a certificate provides non...
Encrypting a CMS envelope<br />static byte[] EncryptForCertificate(    byte[] plaintext,     X509Certificate2 certificate)...
Signing a CMS envelope<br />static byte[] SignWithCertificate(<br />   byte[] plaintext,<br />   X509Certificate2 certific...
Decrypting a CMS envelope<br />static byte[] DecryptEnvelopedCMS(<br />    byte[] envelopeAsBytes)<br />{<br />EnvelopedCm...
Validating X509 Signatures<br />static bool IsSignatureValid(SignedCmssignedCms)<br />{<br />   bool result = false;<br />...
Encrypting and Signing XML<br />XML has standards for Encryption and Signing - XmlEnc & XmlDSig<br />Can encrypt and sign ...
Demo Time!<br />
Encrypting XML<br />private static void EncryptXml(<br />XmlDocument document,<br />    string elementIdToEncrypt,<br />  ...
Decrypting XML<br />private static void DecryptXml(XmlDocumentdocument)<br />{<br />  // Create a new EncryptedXml object ...
Signing XML<br />private static void SignXml(XmlDocument document, X509Certificate2 certificate)<br />{<br />SignedXmlsign...
Validating XML Signatures<br />private static bool VerifySignature(XmlDocument document)<br />{<br />SignedXmlsignedXml = ...
Extracting the signing certificate<br />private static bool VerifySignature(XmlDocument document, out X509Certificate sign...
Links<br />http://www.keylength.com/ - collection of recommended algorithms, key lengths and expiries.<br />http://csrc.ni...
Buy my book<br />Beginning ASP.NET Security<br />Wrox Press<br />ISBN: 978-0470743652<br />Available now!<br />An ideal va...
Upcoming SlideShare
Loading in...5
×

A Developers Guide to Encryption

1,989

Published on

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,989
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
46
Comments
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.

×