This post is my summary of the lightning talk for tonight’s Ruby Meetup in Nashville. I should have known that I’d need a bit more than five minutes to cover an intro to OpenSSL asymmetric encryption… Thank goodness for blogs! In the spirit of a lightning talk, I’ll keep this short an cover only the high-level points of this topic.
A Quick Primer…
Asymmetric cryptography is important in a number of applications and protocols that we use every day and it’s beneficial for software developers to know at least a little bit about the topic. Let’s start with a quick definition… Asymmetric cryptography is a type of cryptographic algorithm that utilizes private/public key pairs for encrypting data. In simplistic terms, data encrypted with a public key may only be decrypted with its corresponding private key and data signed with a private key can be verified with its corresponding public key.
One important use for asymmetric cryptography is for the generation of “digital signatures”. Digital signatures are useful for verifying the identity behind an email message or authentication token (SAML tokens anyone?). Digital signatures are also used to verify the authenticity of software packages. To generate a digital signature, an entity will generate an encrypted hash [serving as the “signature”] based on a digest algorithm (message digest) and some message content (i.e. an email message) using their private key. The message is then sent to a third party along with its digital signature. To verify authenticity of the original message, a third party verifies the encrypted signature hash by using the sender’s public key to decrypt the signature hash and compares the decrypted contents with its own hash of the original message content. If the message hashes match, the message is said to be authentic. If the hashes do not match, the message has been tampered with in some way before it was received.
Taking this a step further, asymmetric cryptography is also used to encrypt the contents of messages. Building on the example above, two parties can send secure messages to each other provided that they first share their public keys. Party X can secure a message for Party Y by encrypting a message using Party Y’s public key. Since the only key able to decrypt the data is Party Y’s private key, the message is unreadable to anyone other than Party Y.
Unfortunately, asymmetric encryption is an extremely slow method of encryption – much slower than symmetric encryption algorithms that use a single key (i.e Advanced Encryption Standard or AES). Web browsers use a combination of asymmetric and symmetric encryption to enforce the SSL/TLS protocols for secure web sites. In this scenario, the web server and browser use asymmetric encryption negotiate a secure key using the website’s SSL certificate and client machine’s security certificate. The negotiated message/key is then used as the encryption key for continued communication using faster symmetric encryption.
This code snippet is a trivial example whereas a single Ruby shell script simulates secure communication between the Nashville Ruby Meetup Group and our favorite patriot, Edward Snowden. The script generates an RSA private/public key pair for each party; exports the public key (to provide to the other party); encrypts a message for each party using the other’s public key; and decrypts the message using each party’s own private key. Additionally, I added message signing and verification to this snippet (although it was not part of my original lightning talk code sample).
KEY_LENGTH = 4096 # Key size (in bits)
digest_fuction = OpenSSL::Digest::SHA256.new # Predetermined signature digest function
# Generate RSA private/public key pairs for both parties...
keypair_snowden = OpenSSL::PKey::RSA.new(KEY_LENGTH)
keypair_meetup = OpenSSL::PKey::RSA.new(KEY_LENGTH)
# Public key export for exchange between parties...
pubkey_snowden = OpenSSL::PKey::RSA.new(keypair_snowden.public_key.to_der)
pubkey_meetup = OpenSSL::PKey::RSA.new(keypair_meetup.public_key.to_der)
# Plain text messages...
message_to_snowden = 'You are a patriot!'
message_to_meetup = "Russia is really nice this time of year...\nUse encryption and make the NSA CPUs churn and burn!"
# Generate digital signatures using private keys...
signature_meetup = keypair_meetup.sign(digest_fuction, message_to_snowden)
signature_snowden = keypair_snowden.sign(digest_fuction, message_to_meetup)
# Encrypt messages using the other party's public key...
encrypted_for_snowden = pubkey_snowden.public_encrypt(message_to_snowden) #from Meetup
encrypted_for_meetup = pubkey_meetup.public_encrypt(message_to_meetup) #from Snowden
# Decrypt messages using own private keys...
decrypted_snowden = keypair_snowden.private_decrypt(encrypted_for_snowden)
decrypted_meetup = keypair_meetup.private_decrypt(encrypted_for_meetup)
# Signature validation and console output...
if pubkey_meetup.verify(digest_fuction, signature_meetup, decrypted_snowden)
puts "Edward Snowden received from Ruby Meetup:"
if pubkey_snowden.verify(digest_fuction, signature_snowden, decrypted_meetup)
puts "Ruby Meetup received from Edward Snowden:"
Why is this Important?
I’m sure by this point, you’re no stranger to the countless news reports of domestic NSA spying. The NSA is capable of seeing just about everything on the Internet including your personal emails regardless of constitutionality or legality. There are also a large number of American organizations, who either by their own will or by NSA influence, provide the NSA with what is essentially an open, unencrypted pipeline to all of your online data. These organizations bypass encryption or provide your data before it has the chance to be encrypted. If that doesn’t scare you, it should… The only way you can ensure the security of your data and your messages is to encrypt that data personally before it’s transmitted over the wire. …and the intent of this post was to show you how that can be done. There’s no guarantee that the NSA won’t eventually be able to decrypt the encrypted messages you send. However, you can and should slow them down a bit by making their servers work a lot harder to get at your personal information. I’m an honest, law-abiding citizen who pays taxes every April 15th and will do so until the day I die. If the NSA choses to read my personal emails to my wife, invoices I send to my clients or anything else that’s either none of their business or NOT a threat to the national security of the United States, then they’re going to have to waste some CPU cycles doing so.
One Last Comment…
Check out GPG Tools. It’s an open-source encryption suite that plugs in to Apple Mail allowing you to sign and encrypt emails using asymmetric encryption. It allows you to create keys with a maximum of 4096 bits and according to the algorithm estimates on keylength.com, there’s a good chance it would take the NSA a while to crack your encryption.