On Not Rolling Your Own Verification or Encryption

November 10, 2011 § Leave a comment


When developing code, there are somethings that you should leave to the experts. Encryption is one of them. When I wrote my encrypted cookies and encrypted cookie sessions gems, one of the the things I didn’t want to do was write any sort of encryption routines. Luckily ActiveSupport has some help in the way of ActiveSupport::MessageEncryptor. It’s used much like ActiveSupport::MessageVerifier which is used for signed cookies in Rails. People much smarter than me have put these pieces together, so it just makes sense to use them. Almost nothing good can come from trying to do this stuff yourself. Here are some examples of a verifier and encryptor being used.

ActiveSupport::MessageVerifier

> secret = ActiveSupport::SecureRandom.hex(10)
 => "379af645b8dcce20b607"

> verifier = ActiveSupport::MessageVerifier.new(secret)
 => #<ActiveSupport::MessageVerifier:0x00000103d7ce50 @secret="379af645b8dcce20b607", @digest="SHA1">

> signed_message = verifier.generate("sign this!")
 => "BAhJIg9zaWduIHRoaXMhBjoGRVQ=--af1e810b074b1abd6d9dcd775f71b1fafa53c218"
# this is "<base 64 encoded and serialized string>--<digest of string>"

> verifier.verify(signed_message)
 => "sign this!"

> verifier.verify(signed_message + "alittleextraontheend")
ActiveSupport::MessageVerifier::InvalidSignature

> verifier.verify("alittleextraatthebeginning" + signed_message)
ActiveSupport::MessageVerifier::InvalidSignature

ActiveSupport::MessgeEncryptor

> secret = ActiveSupport::SecureRandom.hex(20)
 => "c1578de6ec2e1789940729dc9d97b335fc7df588"

> encryptor = ActiveSupport::MessageEncryptor.new(secret)
 => #<ActiveSupport::MessageEncryptor:0x000001295337c8 @secret="c1578de6ec2e1789940729dc9d97b335fc7df588", @cipher="aes-256-cbc">

> encrypted_message = encryptor.encrypt_and_sign("Nothing to see here...")
 => "BAhJIl9YbDZkK0czS3o0ZkI0Yml6K05uYzgzM05meDJjWWU4QWh0YzdFeFFrbC85b3BocHFORWtRWXdDVWIxaW45TEQ5LS1yVkxGTURJYzFWb2pva0UrVkkwTkFnPT0GOgZFRg==--e61e02a818960d66c7865f5624fad63b1564283f"

> encryptor.decrypt_and_verify(encrypted_message)
 => "Nothing to see here..."

If your secret is too short you’ll get a OpenSSL::Cipher::CipherError. Make sure your secret is at least 32 bytes. Using ActiveSupport::SecureRandom.hex(16) should satisfy this requirement, but obviously longer is better. You can also pass in a :digest => <digest> option as a second argument to both initializers to specify a different algorithm to use.

One of my thoughts is to submit these two gems into Rails so that people don’t make the mistake of trying to roll their own encryption systems for cookies. We’ll see how it goes.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

What’s this?

You are currently reading On Not Rolling Your Own Verification or Encryption at The On Blog.

meta

%d bloggers like this: