https://medium.com/@Bakku1505/playing-with-symmetric-encryption-algorithms-in-ruby-8652f105341e Get started Open in app Christian Paling 57 Followers About Follow Sign in Get started Follow 57 Followers About Get started Open in app Playing with symmetric encryption algorithms in Ruby Christian Paling Christian Paling Apr 20, 2016*4 min read In the times where data privacy is a headline every week it is good for software developers to have an understanding of encryption and programming. For Rubyists the standard library of Ruby offers the OpenSSL::Cipher class to use symmetric encryption in Ruby code. Symmetric encryption means that both users who want to communicate are using the same key. This is different to asymmetric encryption where both users do not share the same key. Basics of symmetric encryption algorithms Lets get right into it and fire up our irb. We need to require the openssl library to use its functionalities. > require 'openssl' => true Lets see what kind of symmetric algorithms the Ruby OpenSSL library offers. > puts OpenSSL::Cipher.ciphers As we can see Ruby offers a few algorithms in different varieties. Most ciphers are given using the following format: -- Lets take a few as examples: * Data Encryption Standard (DES) is a widely used encryption algorithm. Today it is not considered as secure and should not be used anymore. * Rivest Cipher/Ron's Code (RC) is a different symmetric algorithm. It is also considered as unsecure and should not be used anymore. (see this) * Advanced Encryption Standard (AES) is a symmetric encryption algorithm which is widely used today and counts as secure Since AES is considered as secure we will use it as our algorithm for now. AES comes with different key bit lengths: 128, 192, 256. The higher the key length is the harder it is to brute force it (try all possible combinations). Eventhough AES128 counts as secure today computers are getting more and more powerful. To ensure that our code will stay secure for a longer period we will use AES256 for our following examples. The different modes of encryption algorithms is out of the scope of this blog post so we will not take a deeper look at them. Just note that encryption algorithms can use different modes to encrypt data. Using OpenSSL::Cipher Let's create a new instance of a AES256 cipher using the CBC mode (as stated above: just ignore the mode since it is not relevant for these examples) > cipher = OpenSSL::Cipher::AES256.new :CBC After obtaining a cipher instance we have to set it to decryption or encryption mode: > cipher.encrypt Normally a cipher needs a key and an initialization vector to encrypt and decrypt a message. The initialization vector should be a random number. After generation it can be transmitted openly and does not need to be kept privately. The algorithm needs an initialization vector (IV) and the key for its encryption process. OpenSSL::Cipher provides a method for generating an IV and should be used to save some hassle. > iv = cipher.random_iv This line does not only generate a random IV and sets it to iv but also sets the initialization vector for this cipher instance. The key is where things get actually interesting. There are different ways to generate keys. One way of course would be to let the computer generate a random key. But a user might want to set the key by himself. A problem is that you cannot take a normal word like SecretPassword as your key since AES256 requires your key to be 256 bit long. > cipher.key = "SecretPassword" OpenSSL::Cipher::CipherError: key length too short By executing the following line > "string".encoding # we can see that a string in my current irb instance is using UTF-8 as encoding which means that one character equals 8 bits. Simple math: 256 / 8 = 32. This means that we need a 32 character string as our key for the AES256 algorithm. Ever had a 32 character long password? Now lets take a key which is long enough and encrypt some data. > cipher.key = "ThisPasswordIsReallyHardToGuess!" Now we have our IV and key set. Now we can encrypt some data. > cipher_text = cipher.update('This is a secret message') + cipher.final cipher.update takes a message and encrypts it using the IV and key given before. cipher.final adds the final part of the cipher text to the end of the encrypted message. This is needed if encrypted data is transmitted so the decrypter knows when the end of the message is reached. Decryption Decrypting works like encrypting: > decipher = OpenSSL::Cipher::AES256.new :CBC > decipher.decrypt > decipher.iv = iv # previously saved > decipher.key = 'ThisPasswordIsReallyHardToGuess!' > plain_text = decipher.update(cipher_text) + decipher.final => "This is a secret message" Different Keys What if we wanted our key just to be SecretPassword? Here we could use a hash. A hash takes something (like a file, a string, ...) and turns it into a fixed number of characters. This fixed number is specified by the hash algorithm which is being used. In our case we want a 256 bit key so we need a hash function which creates 256 bit hashes. For this we can use the SHA-256 hash algorithm. In Ruby we can use the SHA-256 hash algorithm using the digest library. > key = Digest::SHA256.digest 'SecretPassword' This line turns SecretPassword into a 256 bit hash which we can then use as a key for our AES encryption. I hope this little post could give some insights in the world of symmetric encryption. We could not go deep into many aspects of symmetric encryption since it is out of scope for a simple blog post. But if anybody is interested feel free to leave a comment and I can write about a certain topic more specifically. Christian Paling Follow 279 3 279 279 3 * Ruby * Security * Ruby on Rails More from Christian Paling Follow More From Medium How we halved our memory consumption in Rails with jemalloc Carmen Chung in Ruby Inside [1] [1] Using UUIDs to your Rails 6 application Guillaume Occuly in ITNEXT [1] [1] How to Remove Single Table Inheritance from Your Rails Monolith Tracy Lum in Flatiron Labs [1] [1] Speeding Up Your Ruby on Rails App Daniel Lempesis [1] [1] Cut Your RSpec/Minitest Runtime With TestProf Benny Sitbon in Better Programming [1] [1] Using Git Hooks to Run Rubocop, Brakeman, and Rspec Ankit Samarthya in Better Programming [1] [1] Is module_function really the same as extend self ? Mehdi Farsi in RubyCademy [1] [1] Using Custom Ruby Methods in Rails Serializer Sean LaFlam in The Startup [1] [1] About Help Legal Get the Medium app A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store