Cryptography & X.509 Certificates Dominick Baier
Dominick Baier Solution architect and security consultant at thinktecture Focus on security in distributed applications identity management Windows/.NET security cloud computing Microsoft MVP for Developer Security http://www.leastprivilege.com dominick.baier@thinktecture.com 2
Agenda Why cryptography? Symmetric cryptography Asymmetric cryptography X.509 certificates & public key cryptography standards.net APIs 3
Why cryptography? Confidentiality, Integrity, Authenticity Alice Bob 4
Certificates? 5
Certificates?? 6
Certificates??? 7
History: symmetric cryptography Encryption Decryption 8
Symmetric crypto in the.net Framework Cryptography consists of two primitives Hashing integrity protection Encryption confidentiality protection 9
Hash algorithms HashAlgorithm MD5 RIPEMD160 SHA1 MD5CryptoServiceProvider RIPEMD160Managed SHA1Managed SHA1CryptoServiceProvider SHA256 SHA384 SHA512 SHA256Managed SHA384Managed SHA512Managed 10
Creating a hash void SimpleHash() { string data = some data"; byte[] databytes = Encoding.Unicode.GetBytes(data); HashAlgorithm sha = new SHA1Managed(); byte[] hashbytes = sha.computehash(databytes); } string hashstring = Convert.ToBase64String(hashBytes); 11
Stream Ciphers How a stream cipher works key is used as a seed for a pseudo-random-number generator run the PRNG continuously to get a key stream XOR each bit of plaintext with corresponding bit in key stream most common example is RC4 Benefits easy to implement, blazingly fast ciphertext is always exactly the same length as plaintext Drawbacks incredibly easy to misuse most software that uses stream ciphers has at one time been buggy and insecure System.Security.Cryptography doesn t expose them at all 12
Block Ciphers How a block cipher works input is broken up into fixed size blocks (typically 8- or 16-bytes) transformation f() applied to key, result xor d into block this is known as a round 16 to 32 rounds is typical key plaintext block f() xor Round 1 f() xor Round N ciphertext block 13
Encrypting data in.net Setting up choose an algorithm and implementation choose a feedback mode choose a padding mode generate an initialization vector (IV) choose a key Encrypting record the initialization vector for use during decryption create a CryptoStream object based on your key pump data through the stream to encrypt it 14
Algorithms and implementations in.net SymmetricAlgorithm DES DESCryptoServiceProvider TripleDES RC2 TripleDESCryptoServiceProvider RC2CryptoServiceProvider Rijndael RijndaelManaged note that these are all block ciphers 15
Example: encrypting a file void Encrypt(FileStream s, FileStream d) { SymmetricAlgorithm alg = new RijndaelManaged(); alg.mode = CipherMode.CBC; alg.padding = PaddingMode.PKCS7; alg.generateiv(); _writeiv(alg, d); // writes alg.iv to the stream // this example uses a password as a key // more on this later... alg.key = _keyfrompassword(_getpassword()); Stream cryptoutput = new CryptoStream(d, alg.createencryptor(), CryptoStreamMode.Write); } _pump(s, cryptoutput); cryptoutput.close(); 16
Decrypting data in.net Setting up choose the same algorithm you used to encrypt (duh!) choose the same feedback mode choose the same padding mode retrieve the initialization vector (IV) used during encryption retrieve the key Decrypting create a CryptoStream object based on your key pump data through the stream to decrypt it close the CryptoStream immediately when done decrypting this causes it to eat any leftover padding from the input stream 17
Example: decrypting a file void Decrypt(FileStream s, FileStream d) { SymmetricAlgorithm alg = new RijndaelManaged(); alg.mode = CipherMode.CBC; alg.padding = PaddingMode.PKCS7; _readiv(alg, s); alg.key = _keyfrompassword(_getpassword()); Stream cryptoutput = new CryptoStream(d, alg.createdecryptor(), CryptoStreamMode.Write); } _pump(s, cryptoutput); cryptoutput.close(); 18
Passwords as keys Passwords or phrases can be turned into conventional keys variable length passphrase converted into a fixed length key hash of password produces fixed length key Passwords are often long term secrets we limit their use as much as possible to avoid compromise shorter term secrets known as session keys are often used long term secrets such as passwords are usually used to help exchange short term secrets such as session keys Use short term keys to encrypt data whenever possible attacker has less ciphertext to work with to break the key 19
Turning a password into a key static byte[] keyfrompassword(string password) { const int KEY_SIZE = 16; PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, null); } byte[] key = pdb.getbytes(key_size); return key; 20
Reality check password entropy The code you just saw has a huge flaw it accepts passwords of arbitrary quality it always produces a 128-bit key it gives the illusion that you have the protection of a 128-bit key A password that truly has 128-bits of entropy is rare indeed this requires 20 random characters from the following: upper and lower case alpha (A-Z, a-z) digits (0-9) punctuation Be sure to give the user feedback on password quality! consider rejecting passwords with too little entropy 21
Calculating the entropy of a password static double _passwordentropy(string s) { if (0 == s.length) return 0; // first determine the type of characters used int permutations = 0; // psuedo-code for brevity if (useslowercasealpha) permutations += 26; if (usesuppercasealpha) permutations += 26; if (usesnumerics) permutations += 10; if (usespunctuation) permutations += 32; double passwordentropy = Math.Log10(Math.Pow(permutations, s.length)) / Math.Log10(2); } return passwordentropy; Note this calculation is totally bogus if password contains words found in a dictionary! 22
Password lengths 23
History: asymmetric cryptography Alice Bob Bob Bob Alice Alice 24
Problem solved? Not really public key cryptography is too slow to handle large data initial key exchange prone to Man-in-the-Middle attacks asymmetric key symmetric (session) key 25
History: X509 certificates Carla Alice Bob 26
History: X509 certificates ASN.1 encoded file containing public key additional information about owner and issuer expiration and purpose information revocation information digital signature to prevent manipulation All problems solved? how to bootstrap trust? leads to Public Key Infrastructure (PKI) 27
Solution (or at least where we are currently) X.509 certificates provide authentication for public keys Public keys used to securely transmit session key Session key used to encrypt/sign bulk data X.509 certificate asymmetric key symmetric (session) key 28
Example: SSL CRL check connect send certificate generate session key & encrypt with public key 29
How to get a certificate Depends on how you can bootstrap trust Public facing applications typically buy a certificate from a company that is already trusted (Verisign, TrustCenter etc..) Intranet applications often internal CA/PKI Test/Development internal PKI test/development CA makecert.exe 30
Makecert.exe Command line tool to generate certificates & private keys makecert -r -n "CN=TestCertificate" -a sha1 -sv TestCert.pvk TestCert.cer // self signed // name // sig. algo // priv. Key // certificate 31
Makecert.exe creating a test root Can be used to sign leaf certificates makecert -r -n "CN=Test Root Authority" -a sha1 -sky signature -sv TestRoot.pvk TestRoot.cer // self signed // subject name // sig. algo. // use for sig. // private key // certificate 32
Makecert.exe creating issued certificates Can be used to sign leaf certificates makecert -n "CN=TestCert" -a sha1 -sky exchange -sv TestCert.pvk -iv TestRoot.pvk -ic TestRoot.cer TestCert.cer // subject name // sig. algo. // use for ex. // private key // root priv key // root certificate // certificate 33
Windows Certificate Services UI and management features for certificates 34
The Windows Certificate Store Abstraction of physical storage of certificates / private keys hard disk, smart card, hardware storage module unified API 35
The Windows Certificate Store Computer store machine wide certificates trusted root certification authorities private keys are ACL ed for Administrators and SYSTEM User store one store per (user) account stored in account profile only accessible to the corresponding user All private keys are encrypted with machine/user key 36
Using the certificate store Importing certificates makecert.exe & certificate services allow deployment directly to the certificate store import.cer &.pfx (or.p12) files pvk2pfx.exe certutil.exe & winhttpcertcfg.exe API Accessing certificates MMC snap-in System.Security.Cryptography.X509Certificates X509Store & X509Certificate2 class UI helpers 37
Common gotcha: ACLs Certificates (& private keys) must be deployed to the store of the corresponding user Some hosting environments don t load the user profile IIS <7 in this case keys must be deployed to machine store private key must be explicitly ACL ed for worker account How? keyset does not exist certificates MMC Vista+ winhttpcertcfg.exe programmatically 38
Certificate specific APIs System.Security.Cryptography.X509Certificates X509Store, X509Certificate2, X509Chain System.Security.Cryptography.PKCS implementation of PKCS#7 CMS standard digital signatures & encryption for arbitrary data interoperable 39
Typical use of the certificate store Programmatically 40
Typical use of the certificate store Declarative 41
UI helpers Standard Windows dialogs used by Explorer, IIS... 42
UI helpers 43
Overview of PKCS#7 support in.net ContentInfo SignedCms EnvelopedCms CmsSigner.Encode() CmsRecipient Standard PKCS#7 SignedData Standard PKCS#7 EnvelopedData 44
Example: signing data byte[] sign(byte[] input, X509Certificate2 certificate) { // what is signed ContentInfo content = new ContentInfo(input); // who signs CmsSigner signer = new CmsSigner(certificate); // represents a signed message SignedCms signedmessage = new SignedCms(content); // sign the message signedmessage.computesignature(signer); } // serialize the message return signedmessage.encode(); 45
What we just produced plaintext message signer Cert issuer Cert serial number hash of message encrypted with the private key of signer 46
Example: encryption using certificates byte[] encrypt(x509certificate2 cert, byte[] input) { // what is encrypted ContentInfo contentinfo = new ContentInfo(input); EnvelopedCms envelopedmessage = new EnvelopedCms(contentInfo); // who can decrypt CmsRecipient recipient = new CmsRecipient(cert); // encrypt message envelopedmessage.encrypt(recipient); } // serialize the message return envelopedmessage.encode(); 47
What we just produced (signed) data encrypted with session key recipient Cert issuer Cert serial number session key encrypted with the public key of recipient 48
Decrypting an enveloped message static byte[] Decrypt(byte[] data) { // create EnvelopedCms and deserialize EnvelopedCms encryptedmessage = new EnvelopedCms(); encryptedmessage.decode(data); // decrypt encryptedmessage.decrypt(); } // return plain text return encryptedmessage.contentinfo.content; 49
Verifying the signature void checksignature(signedcms signedmessage) { // true checks signature only signedmessage.checksignature(true); } foreach (SignerInfo signerinfo in signedmessage.signerinfos) { // access the certificate X509Certificate2 cert = signerinfo.certificate; } 50
Verifying certificates Just because the signature matches the public key doesn t mean it s a valid signature you need to check the validity of the certificate itself this means looking all the way up the chain of trust this means looking for revoked certificates Certificate Revocation Lists (CRL) are important authorities that issue certificates also publish CRLs regularly.net allows you to check against CRLs, but it s not automatic 51
Example: verifying a certificate void VerifyCert(X509Certificate2 cert) { // set up verification policy X509Chain chain = new X509Chain(); chain.chainpolicy.revocationmode = X509RevocationMode.Online X509RevocationMode.Offline; chain.chainpolicy.revocationflag = X509RevocationFlag.EntireChain; chain.chainpolicy.urlretrievaltimeout = new TimeSpan(5000); chain.chainpolicy.verificationtime = DateTime.Now; } // verify certificate if (!chain.build(cert)) { // iterate through error information foreach (X509ChainElement e in chain.chainelements) { } } 52
.NET APIs that use X509Certificate2 System.Net.HttpWebRequest whenever https:// is used ServicePointManager to control behavior System.Net.Security.SslStream implements SSL over arbitrary stream for clients and servers System.Web.HttpRequest access to SSL client certificates System.Net.Mail.SmtpClient SMTP over SSL support System.Security.Cryptography.Xml.* W3C signed/encrypted XML System.ServiceModel.* e.g. WS-Security 53
Summary.NET has full featured crypto support Certificates are everywhere It is a complex topic, but as a developer you typically care about the certificate store (and ACLs) trust chain CRL list expiration date Building a test/development CA makes it much easier 54
Resources How to build a test/dev CA http://www.leastprivilege.com/howtobuildadevelopmenttestdemoca.aspx Makecert.exe http://msdn.microsoft.com/en-us/library/bfsktky3(vs.71).aspx CertUtil.exe http://technet.microsoft.com/en-us/library/cc732443(ws.10).aspx Pvk2Pfx.exe http://msdn.microsoft.com/en-us/library/dd434714.aspx WinHttpCertCfg.exe http://www.microsoft.com/downloads/details.aspx?familyid=c42e27ac- 3409-40e9-8667-c748e422833f&displaylang=en How to get to a private key file programmatically http://www.leastprivilege.com/howtogettotheprivatekeyfilefroma Certificate.aspx 55