# A Developer’s Guide to Encryption - PowerPoint PPT Presentation

1 / 50

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

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

A Developer’s Guide to Encryption

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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

## 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

• Asymmetric Encryption

• Manual Asymmetric Encryption

• X509 Certificates

• Message Authentication Codes

• Encrypting and Signing XML

### 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.

### Definitions

• Plaintext / Cleartext – Unencrypted Data.

• Ciphertext –Encrypted Data.

• Cipher –Encryption algorithm.

### Random Numbers

• Cryptography needs random numbers.

• Random isn’t really random.

• PRNG – Pseudo Random Number Generator.

### 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;

}

### Hardware RNGs

• Based on

• Background noise,

• Other entropy source.

• Specialised Hardware.

• But now even Intel Chipsets have hardware RNGs.

• (Post Office Ernie)

### 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.

### Generating a hash

HashAlgorithmalgorithm = new SHA256Managed();

byte[] hash = algorithm.ComputeHash(plaintext);

### 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.

### 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.

### 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);

### 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;

}

### Encryption Keys

• Once you lose them change the “locks”.

• Keys are like condoms -

don’t reuse them.

### Symmetric Encryption

• A single key is used for encryption and decryption.

• Fast, computationally cheap.

• Needs a shared key.

• Repudiable.

### Symmetric Keys

• Keys are cryptographically secure random data.

• Size of key depends on algorithm.

### 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

### 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();

### 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();

### Symmetric Encryption Algorithms

• DES

• TripleDES

• Rivest Cipher 2

• Rijndael/AES

• DES/RC considered unsafe.

• Rijndael is the most commonly used.

• RFC2898 derives a key and IV from a password and a salt

SymmetricAlgorithmsymmetricAlgorithm,

ref byte[] key, ref byte[] iv)

{

Rfc2898DeriveBytes rfc2898DeriveBytes =

key =

rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.KeySize/ 8);

iv =

rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.BlockSize/ 8);

}

### 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.

### Generating a MAC

private static byte[] CalculateMAC( byte[] plainText, byte[] key)

{

HMACSHA256 hmac = new HMACSHA256(key);

return hmac.ComputeHash(plainText);

}

### 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.

### 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);

### 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);

### 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

### 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

{

X509Store certificateStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);

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];

}

### Encrypting With A Certificate

RSACryptoServiceProviderencryptionProvider = (RSACryptoServiceProvider)certificate.PublicKey.Key;

byte[] cipherText= encryptionProvider.Encrypt(plaintextAsBytes, true));

### Decrypting With A Certificate

if (!certificate.HasPrivateKey)

throw new CryptographicException(

"No private key.");

RSACryptoServiceProviderencryptionProvider = (RSACryptoServiceProvider)certificate;

byte[] plaintext = encryptionProvider.Decrypt(ciphertextAsBytes, true));

### Envelopes & Signing with certificates

• Signing guarantees data integrity.

• Signing with a certificate provides non-repudiation.

• CMS / PKCS #7 is the standard envelope format.

### 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();

}

### 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();

}

### Decrypting a CMS envelope

static byte[] DecryptEnvelopedCMS(

byte[] envelopeAsBytes)

{

EnvelopedCmsenvelopedCms =

new EnvelopedCms();

envelopedCms.Decode(envelopeAsBytes);

envelopedCms.Decrypt();

return envelopedCms.ContentInfo.Content;

}

### 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;

}

### 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.

### 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)

{

}

// 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);

}

### Decrypting XML

private static void DecryptXml(XmlDocumentdocument)

{

// Create a new EncryptedXml object // from the document

EncryptedXmlencryptedXml = new EncryptedXml(document);

// Decrypt the document.

encryptedXml.DecryptDocument();

}

### 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();

XmlDsigEnvelopedSignatureTransformenvelope = new XmlDsigEnvelopedSignatureTransform();

KeyInfokeyInfo = new KeyInfo();

signedXml.KeyInfo = keyInfo;

signedXml.ComputeSignature();

XmlElementxmlDigitalSignature = signedXml.GetXml();

document.DocumentElement.AppendChild(document.ImportNode(xmlDigitalSignature, true));

}

### 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.");

}

return signedXml.CheckSignature();

}

### 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.");

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();

}

• 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