Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Simply encrypt and decrypt Strings in Ruby.
require 'openssl'
class String
def encrypt(key)
cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').encrypt
cipher.key = Digest::SHA1.hexdigest key
s = cipher.update(self) + cipher.final
s.unpack('H*')[0].upcase
end
def decrypt(key)
cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').decrypt
cipher.key = Digest::SHA1.hexdigest key
s = [self].pack("H*").unpack("C*").pack("c*")
cipher.update(s) + cipher.final
end
end
puts plain = 'confidential' # confidential
puts key = 'secret' # secret
puts cipher = plain.encrypt(key) # 5C6D4C5FAFFCF09F271E01C5A132BE89
puts cipher.decrypt('guess') # raises OpenSSL::Cipher::CipherError
puts cipher.decrypt(key) # confidential
@leduytung

This comment has been minimized.

Copy link

commented Jul 24, 2017

Nice :) , 2017 and still works

@xiaohui-zhangxh

This comment has been minimized.

Copy link

commented Aug 13, 2017

Very helpful, thanks

@bater

This comment has been minimized.

Copy link

commented Sep 1, 2017

I got key must be 24 bytes message at this line:

cipher.key = Digest::SHA1.hexdigest key

so I change to like this

key = cipher.random_key
cipher.key = key

It will always fit.

Reference http://ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/Cipher.html

@grammakov

This comment has been minimized.

Copy link

commented Apr 5, 2018

To avoid deprecation messages change

cipher = OpenSSL::Cipher::Cipher.new('DES-EDE3-CBC').decrypt

to

cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').decrypt
@TiredOfProgramming

This comment has been minimized.

Copy link

commented May 15, 2018

Doesn't work for me. Getting no implicit conversion of Object into String (TypeError) on line s = [self].pack("H*").unpack("C*").pack("c*")

@wteuber

This comment has been minimized.

Copy link
Owner Author

commented Aug 23, 2018

@TiredOfProgramming
The provided code monkey-patches the class String and works only there. If you want to use it another class (e.g. Object), you need to define the string to encrypt or decrypt separately, e.g.

require 'openssl'

def encrypt(plain_text, key)
  cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').encrypt
  cipher.key = Digest::SHA1.hexdigest key
  s = cipher.update(plain_text) + cipher.final

  s.unpack('H*')[0].upcase
end

def decrypt(cipher_text, key)
  cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').decrypt
  cipher.key = Digest::SHA1.hexdigest key
  s = [cipher_text].pack("H*").unpack("C*").pack("c*")

  cipher.update(s) + cipher.final
end

puts plain = 'confidential'            # confidential
puts key = 'secret'                    # secret
puts cipher = encrypt(plain, key)      # 5C6D4C5FAFFCF09F271E01C5A132BE89

puts decrypt(cipher, 'guess')          # raises OpenSSL::Cipher::CipherError
puts decrypt(cipher, key)              # confidential

I hope you find that helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.