lib/rcs-common/crypt.rb
#
# The encryption module.
# by default we use the PKCS5 padding
# force the third parameter to change the padding
#
require 'openssl'
require 'digest/sha1'
module RCS
module Crypt
PAD_NOPAD = 0
PAD_PKCS5 = 1
SHA1_DIGEST_LENGTH = 20
def aes_encrypt(clear_text, key, padding=PAD_PKCS5)
cipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
cipher.encrypt
cipher.padding = padding
cipher.key = key
cipher.iv = "\x00" * cipher.iv_len
edata = cipher.update(clear_text)
edata << cipher.final
return edata
end
def aes_decrypt(enc_text, key, padding=PAD_PKCS5)
decipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
decipher.decrypt
decipher.padding = padding
decipher.key = key
decipher.iv = "\x00" * decipher.iv_len
data = decipher.update(enc_text)
data << decipher.final
return data
end
def aes_encrypt_integrity(clear_text, key, padding=PAD_PKCS5)
# add the integrity check at the end of the message
clear_text += Digest::SHA1.digest(clear_text)
return aes_encrypt(clear_text, key, padding)
end
def aes_decrypt_integrity(enc_text, key, padding=PAD_PKCS5)
text = aes_decrypt(enc_text, key, padding)
# check the integrity at the end of the message
check = text.slice!(text.length - SHA1_DIGEST_LENGTH, text.length)
raise "Invalid sha1 check" unless check == Digest::SHA1.digest(text)
return text
end
end
end #namespace
if __FILE__ == $0
require 'securerandom'
include RCS::Crypt
clear = SecureRandom.random_bytes(16)
key = Digest::MD5.digest "4yeN5zu0+il3Jtcb5a1sBcAdjYFcsD9z"
puts "DATA: " + clear.unpack('H*').to_s
enc = aes_encrypt(clear, key)
puts "ENC: " + enc.unpack('H*').to_s
dec = aes_decrypt(enc, key)
puts "DEC: " + dec.unpack('H*').to_s
end