-
-
Save wteuber/5318013 to your computer and use it in GitHub Desktop.
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 |
Very helpful, thanks
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
To avoid deprecation messages change
cipher = OpenSSL::Cipher::Cipher.new('DES-EDE3-CBC').decrypt
to
cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').decrypt
Doesn't work for me. Getting no implicit conversion of Object into String (TypeError)
on line s = [self].pack("H*").unpack("C*").pack("c*")
@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.
When I try to set encrypter.key I always get this error message: key must be 24 bytes. Here's my complete script:
#!/usr/bin/ruby -w
require 'openssl'
key = 'my-secret-key'
cipher = OpenSSL::Cipher.new('DES-EDE3-CBC')
encrypter = cipher.encrypt
encrypter.key = Digest::SHA1.hexdigest(key)
I'm running ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]. The OS is Ubuntu 18.04.3 LTS.
I should also mention that this script works fine on an Ubuntu 17 machine with Ruby version ruby 2.3.3p222 (2016-11-21) [x86_64-linux-gnu]. The OS is Ubuntu 17.10.
Any help is appreciated.
@mikosullivan key is used in different context. In this gist, key is a cipher "password". You are trying to set the "encryption key". Consider using your key as cipher password and generate a secure random key. Check out Ruby's documentation for encrypt and key and the section Choosing a key.
If you absolutely need to use passwords as encryption keys, you should use Password-Based Key Derivation Function 2 (PBKDF2) by generating the key with the help of the functionality provided by OpenSSL::PKCS5.pbkdf2_hmac_sha1 or OpenSSL::PKCS5.pbkdf2_hmac.
Although there is #pkcs5_keyivgen, its use is deprecated and it should only be used in legacy applications because it does not use the newer PKCS#5 v2 algorithms.
I suggest, you don't use a password, but generate a secure (random) key. Store it somewhere safe, e.g. base64-encoded.
require 'openssl'
key = 'my-secret-key'
cipher = OpenSSL::Cipher.new('DES-EDE3-CBC')
encrypter = cipher.encrypt
encrypter.key_len
# => 24
encrypter.key = encrypter.random_key
my complete solution is:
require 'openssl'
class String
def encrypt(key)
cipher = OpenSSL::Cipher::AES.new(128, :CBC).encrypt
cipher.key = key
cipher.update(self) + cipher.final
end
def decrypt(key)
cipher = OpenSSL::Cipher::AES.new(128, :CBC).decrypt
cipher.key = key
cipher.update(self) + cipher.final
end
end
keygen = OpenSSL::Cipher::AES.new(128, :CBC).encrypt
key = keygen.random_key
encrypted = "geheim".encrypt(key)
encrypted.decrypt(key) # => geheim
avoiding key must be 24 bytes
def encrypt(key)
cipher = OpenSSL::Cipher.new("aes-256-cbc").encrypt
cipher.key = Digest::MD5.hexdigest key
s = cipher.update(self) + cipher.final
s.unpack('H*')[0].upcase
end
def decrypt(key)
cipher = OpenSSL::Cipher.new('aes-256-cbc').decrypt
cipher.key = Digest::MD5.hexdigest key
s = [self].pack("H*").unpack("C*").pack("c*")
cipher.update(s) + cipher.final
end
avoiding
key must be 24 bytes
def encrypt(key) cipher = OpenSSL::Cipher.new("aes-256-cbc").encrypt cipher.key = Digest::MD5.hexdigest key s = cipher.update(self) + cipher.final s.unpack('H*')[0].upcase end def decrypt(key) cipher = OpenSSL::Cipher.new('aes-256-cbc').decrypt cipher.key = Digest::MD5.hexdigest key s = [self].pack("H*").unpack("C*").pack("c*") cipher.update(s) + cipher.final end
thanks, works perfectly!
Nice :) , 2017 and still works