Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Can you keep a secret?

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Can you keep a secret?

For thousands of years we have been trying to find ways to keep information secret and work out what other people's secret information is. Today we have cryptographic algorithms that our own government's security and intelligence organisations claim they can't crack. However, security breaches, compromised passwords, stolen credit card details, etc. feature in the news regularly, and the perpetrators aren't government experts, they're amateurs.

Can you keep a secret? The anecdotal evidence would suggest the answer is a resounding no! In this talk I'll introduce you to some cryptographic principles and show how you can make use of them in .NET and how they can be used correctly.

This talk was given at .NET South West on Wednesday 19 August 2015
http://www.meetup.com/dotnetsouthwest/events/224369860/

Avatar for Owain Williams

Owain Williams

August 19, 2015
Tweet

Other Decks in Programming

Transcript

  1. • The Caesar cipher is a shift cipher that moves

    each character 3 places. attack at dawn becomes DWWDFN DW GDZQ • Easy to decrypt, just try every combination, there’s only 25 maximum possibilities! CVVCEM CV FCYP BUUBDL BU EBXO ATTACK AT DAWN Caesar Cipher
  2. • Every plaintext character maps to different ciphertext character. a

    b c d e f g h i j k l m n o p q r s t u v w x y z J L P A W I Q B C T R Z Y D S K E G F X H U O N V M • 403,291,461,126,605,635,584,000,000 combinations • The cipher doesn’t hide any of the statistics of the underlying language. • Frequency analysis, character repetition and word boundaries are all useful in breaking these ciphers. Monoalphabetic Substitution Cipher
  3. • Uses multiple substitution alphabets. • Vigenère cipher, Le Chiffre

    Indéchiffrable and even Enigma are all examples of a polyalphabetic substitution cipher. • Frequency analysis is much harder. • However, some underlying statistics are still present. • These can all be cracked by computers fairly quickly. • Enigma was sold by the Brits to foreign governments after the war because we knew we could crack it! Polyalphabetic Cipher
  4. • Integrated circuit heralded a new era of computing. •

    IBM’s Lucifer system was incredibly secure. • So secure that the NSA limited it to a 56-bit key length and rebadged it the Data Encryption Standard (DES) • Advanced Encryption Standard (AES) now uses a key size of up to 256-bits. • “brute-force attacks against 256-bit keys will be infeasible until computers are built from something other than matter and occupy something other than space.” - Bruice Schneier, Applied Cryptography. Modern Ciphers
  5. void Encrypt(Stream input, Stream output, byte[] key) void Decrypt(Stream input,

    Stream output, byte[] key) { using (var algorithm = Aes.Create()) { using (var algorithm = Aes.Create()) { algorithm.Mode = CipherMode.ECB; algorithm.Key = key; { algorithm.Mode = CipherMode.ECB; algorithm.Key = key; using (var cryptoStream = new CryptoStream(output, algorithm.CreateEncryptor(), CryptoStreamMode.Write)) using (var cryptoStream = new CryptoStream(input, algorithm.CreateDecryptor(), CryptoStreamMode.Read)) { input.CopyTo(cryptoStream); { cryptoStream.CopyTo(output); } } } cryptoStream.FlushFinalBlock(); } } } The quick brown fox jumped over the lazy dog iGtx9xU7TU7PNl5qDNHAYaSeJcL3bIwW 4444 oXC5fDRuNzkp6g1E
  6. Electronic Code Book (ECB) • Same block of plaintext will

    always encrypt to the same block of ciphertext.
  7. • Repeating patterns will still exist in the ciphertext. •

    Most obvious in bitmap images that have regions of the same colour. Electronic Code Book (ECB)
  8. • XOR each block of plaintext with the previous block

    of ciphertext. • Produces a pseudo-random stream that hides any underlying pattern in the plaintext. • This is the default for the Aes Class in .NET • Requires an Initialisation Vector (IV) because the first block of plaintext won’t have anything to be XORed with. Cipher Block Chaining (CBC)
  9. void Encrypt(Stream input, Stream output, byte[] key) { using (var

    algorithm = Aes.Create()) { void Decrypt(Stream input, Stream output, byte[] key) { using (var algorithm = Aes.Create()) { algorithm.Key = key; algorithm.Key = key; output.Write(algorithm.IV, 0, algorithm.IV.Length); var iv = algorithm.IV; input.Read(iv, 0, iv.Length); algorithm.IV = iv; using (var cryptoStream = new CryptoStream(output, algorithm.CreateEncryptor(), CryptoStreamMode.Write)) { input.CopyTo(cryptoStream); cryptoStream.FlushFinalBlock(); } } } using (var cryptoStream = new CryptoStream(input, algorithm.CreateDecryptor(), CryptoStreamMode.Read)) { cryptoStream.CopyTo(output); } } } The quick brown fox jumped over the lazy dog iGtx9xU7TU7PNl5qDNHAYaSeJcL3bIwW 4444 oXC5fDRuNzkp6g1E bnfWloNh06Uc74K8 F4s9YkDZ31erCbVot8HcwbgibgjuNgoW RFjbadXoCj7d6jRu
  10. • Where should we store the key? • If it’s

    in a config file, anyone with access to the source code will have access to the key. • We could encrypt the key, but what key would you use to encrypt the key? • This is where the Key Management Service (KMS) from Amazon Web Services (AWS) can help. • You decide who has access to the key. • Key usage can be audited. • Integrates with EBS, S3 and RDS Key Management Service (KMS)
  11. void Encrypt(Stream input, Stream output, string arn) void Decrypt(Stream input,

    Stream output, string arn) { var dataKey = kms.GenerateDataKey( new GenerateDataKeyRequest { KeyId = arn, KeySpec = DataKeySpec.AES_256 }); { using (var kms = new AmazonKeyManagementServiceClient()) using (var algorithm = Aes.Create()) output.WriteByte((byte)dataKey.CiphertextBlob.Length); dataKey.CiphertextBlob.CopyTo(output); algorithm.Key = dataKey.Plaintext.ToArray(); output.Write(algorithm.IV, 0, algorithm.IV.Length); using (var cryptoStream = new CryptoStream(output, algorithm.CreateEncryptor(), CryptoStreamMode.Write)) { input.CopyTo(cryptoStream); cryptoStream.FlushFinalBlock(); } } } { using (var kms = new AmazonKeyManagementServiceClient()) using (var algorithm = Aes.Create()) { var length = input.ReadByte(); var buffer = new byte[length]; input.Read(buffer, 0, length); var decryptedData = kms.Decrypt(new DecryptRequest { CiphertextBlob = new MemoryStream(buffer) }); algorithm.Key = decryptedData.Plaintext.ToArray(); var iv = algorithm.IV; input.Read(iv, 0, iv.Length); algorithm.IV = iv; using (var cryptoStream = new CryptoStream(input, algorithm.CreateDecryptor(), CryptoStreamMode.Read)) { cryptoStream.CopyTo(output); } } }
  12. Hashing Algorithms • Take an arbitrary amount of data, this

    could be one byte or several gigabytes, and produces a fixed length output called a digest. • Good for storing passwords. • Same password always hashes to the same digest. • Algorithm is one, there’s no way to recover the data from the digest. • MD5, RIPEMD and SHA are popular algorithms var digest = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(password));
  13. • An adversary signs up 100 dummy accounts using the

    100 most popular passwords. • Then, if he can also steal the database he can compare the hashes for his 100 dummy accounts and match them to all other users. • Store a unique salt, simply random data, against each user. • Combine password and salt when hashing Salt var digest = SHA256 .Create() .ComputeHash(Encoding.UTF8.GetBytes(password).Concat(salt).ToArray());
  14. • Symmetric encryption is analogous to a briefcase with a

    combination lock. • A network of 5 people need 15 different briefcases. • A network of 100 needs 5,050 briefcases. • Diffie and Hellman created key exchange algorithm. • Rivest, Shamir & Adleman created RSA. • Asymmetric encryption is analogous to a padlock. • Anyone can close the padlock, but only the key-holder can open the padlock. Symmetric vs Asymmetric
  15. void GenerateKeyPair(int keySize, string privateKeyFilename, string publicKeyFilename) { // Retrieve

    the key pair from the algorithm. var rsaKeyPair = rsa.ToXmlString(true); var keyBytes = Encoding.UTF8.GetBytes(rsaKeyPair); { using (var rsa = new RSACryptoServiceProvider(keySize)) // Protect the key pair using the current user's DPAPI key. keyBytes = ProtectedData.Protect( keyBytes, null, DataProtectionScope.CurrentUser); // Save the encrypted private key data to file. using (var privateKeyFile = new FileStream(privateKeyFilename, FileMode.Create)) { privateKeyFile.Write(keyBytes, 0, keyBytes.Length); } // Save the public key data to file. using (var publicKeyFile = new StreamWriter(publicKeyFilename)) { publicKeyFile.Write(rsa.ToXmlString(false)); } } }
  16. • Alice can now generate a key pair using: GenerateKeyPair(4096,

    "C:\\alicePrivate.xml", "C:\\alicePublic.xml") • She must keep the private key secure, but can publish the public key. • Bob can encrypt messages to Alice by using her public key • Even if Eve has Bob’s encrypted message and Alice’s public key, she cannot read the message. Public/Private Key Cryptography
  17. byte[] Encrypt(byte[] plaintext, string publicKeyFile) { // Load the public

    key data from the key file. using (var file = new StreamReader(publicKeyFile)) { using (var rsa = new RSACryptoServiceProvider()) { // Insert the public key into the RSA algorithm. rsa.FromXmlString(file.ReadToEnd()); // Encrypt the data using the recipients public key. return rsa.Encrypt(plaintext, true); } } }
  18. byte[] Decrypt(byte[] ciphertext, string privateKeyFile) { using (var rsa =

    new RSACryptoServiceProvider()) { // Retrieve the private key from the key file. ReadPrivateKey(rsa, privateKeyFile); // Decrypt the data using the private key. return rsa.Decrypt(ciphertext, true); } } void ReadPrivateKey(RSACryptoServiceProvider rsa, string keyFile) { // Load the private key data from the key file. byte[] keyBytes; using (var file = new FileStream(keyFile, FileMode.Open)) { keyBytes = new byte[file.Length]; file.Read(keyBytes, 0, (int)file.Length); } // Decrypt the key using the current user's DPAPI key. keyBytes = ProtectedData.Unprotect( keyBytes, null, DataProtectionScope.CurrentUser); // Insert the key pair into the RSA algorithm. rsa.FromXmlString(Encoding.UTF8.GetString(keyBytes)); }
  19. • RSA uses massive prime numbers (several hundred digits long),

    this is extremely complicated and slow. • We can combine RSA and AES to get the best of both. • Alice generates a random AES session key. • She encrypts it with RSA and Bob’s public key. • Bob uses his private key to decrypt the session key. • They continue their conversation using AES. • This is virtually enforced in .NET as the RSACryptoServiceProvider limits encryption to 4k. Symmetric & Asymmetric Together
  20. • How does Bob know who the message came from?

    • We can use the Private Key to encrypt and others can use our Public Key to decrypt. • Then anyone can read the message! • If we encrypt the message twice, once with Bob’s Public Key and then with our Private Key they can’t. • What if the message is larger than 4K? • We can use a hashing algorithm to generate a digest and just encrypt that using our Private Key. Digital Signatures
  21. • Alice hashes her message and encrypts the digest with

    her own Private Key. • Alice encrypts the message with Bob’s Public Key. • Bob decrypts the message using his Private Key. • Bob decrypts the digest Alice sent using her Public Key. • Bob hashes the message and compares the digest with the one he decrypted. • If they match he can be sure the message came from Alice. Digital Signatures
  22. • We can use digital signatures to sign our certificates.

    • This is what Verisign, DigiCert, Thawte, etc. do. • Secure (https) web pages use all of these cryptographic principles (and more). • Every time you hit F5 on Gmail your browser is using symmetric encryption, asymmetric encryption, hashing algorithms, random number generators and digital signatures Putting It All Together