0

I have been using the following code in my app for the past year and have 200k record using this code:

options = { :algorithm => 'aes-256-cbc', :value => "changethis", :key => "secretkey" }
cipher = OpenSSL::Cipher::Cipher.new(options[:algorithm])
cipher.send(:encrypt)    
cipher.pkcs5_keyivgen(options[:key])
result = cipher.update(options[:value])
result << cipher.final
# => "x\xED\x14s\xFD\x0E\x97\xC5\x996[M\x1E\x94\xDEI"

I am required (by business) to refactor the pkcs5_keyivgen part, to do it correctly: For example,

options = { :algorithm => 'aes-256-cbc', :value => "changethis", :key => "secretkey" }
cipher = OpenSSL::Cipher::Cipher.new(options[:algorithm])
cipher.send(:encrypt)
cipher.key = '' # ??? 1) How does pkcs5_keyivgen in above code generate key, or does it just use my options[:key]
cipher.iv = '' # ??? 2) How does pkcs5_keyivgen in above code generate iv
result = cipher.update(options[:value])
result << cipher.final

I have to figure out how pkcs5_keyivgen sets key and iv. ideas here? We are using ruby-1.9.3-p286 and encryptor-1.1.3

I saw this question and this question, but they haven't help me solve the problem.

Community
  • 1
  • 1
Kamilski81
  • 14,409
  • 33
  • 108
  • 161
  • I'm not sure why this is being proposed to be closed? It is a programming question? would you please give feedback why you downvote, so i can improve the question. thank you. – Kamilski81 Jul 26 '13 at 14:22

1 Answers1

4

Was trying to solve this problem, but I think there is no easy solution or i just can't see one). Pkcs5_keyivgen() is deprecated and implements non-standard pass key derivation for AES 256.

From this docs and this source code

Pkcs5_keyivgen (pass, SALT = nil, num = 2048, digest = "MD5") -> nil 

Generates some key and IV from salt and pass. No salt in your case. Generation method is defined in v1.5 PKCS #5 (deprecated)

So you are looking for "Password Based Key Derivation Function". PBKDF1

Pkcs5_keyivgen() function calls EVP_BytesToKey() from Openssl and EVP_BytesToKey() generates key bytes for larger key size in a non-standard way

So MD5 generates hash of size EVP_MAX_MD_SIZE (16 + 20) // 16 for MD5

But AES key(32) + IV(16) sizes > EVP_MAX_MD_SIZE, so AES 256 will need multiple hashes to generate random key and IV. Here is source code of algorithm in C

And here is nice pseudo-code explanation of the EVP_BytesToKey()

If you really want to re-implement PBKDF1 here is also RTC2898 standard for PBKDF1 But i don't think that it is a good idea to implement crypto yourself

Community
  • 1
  • 1
varren
  • 14,551
  • 2
  • 41
  • 72
  • Amazing feedback. The true reason i am trying to reverse engineer this is because i need to use it in a Python program as well and sound like I may have to re-implement my ruby the standard way and then do it in python the standard way as well. – Kamilski81 Jul 27 '13 at 14:24
  • [OpenSSL 1.1.0c changed the digest algorithm](http://stackoverflow.com/q/39637388/608639) used in some internal components. Formerly, MD5 was used, and 1.1.0 switched to SHA256. Be careful the change is not affecting you in both `EVP_BytesToKey` and commands like `openssl enc`. – jww Jan 26 '17 at 16:16