From: "Martin Boßlet" Date: 2012-06-11T07:48:18+09:00 Subject: Re: OpenSSL: Determining initialization vector (IV) created using OpenSSL::Cipher::Cipher#pkcs5_keyivgen with one argument Hi Susan, > I realize this method is only PKCS5 v1.5 compliant (rather than 2.0 > compliant) and that we should not be using it, but the conversion to setting > a known random initialization vector (IV) is in a medium/long term phase. > What I would like to be able to figure out in the near-term is: > > (a) how to read the C code above. From my rusty understanding of general C > and virtually zero understanding (despite attempting to find Ruby/C docs but > they appear to be out of date?) of Ruby/C APIs The salt variable should > still be NULL since now vsalt (second argument) was created. salt is initialized as null, but later set in the line salt = (unsigned char *)RSTRING_PTR(vsalt); The Ruby String vsalt's value is assigned to salt there. > (b) at some point I would love to learn how to debug this myself. i.e. setup > my environment to trace the C code in the Ruby MRI runtime so I can fish for > myself next time. You may simply use gdb or if you prefer some comfort, I frequently use Netbeans to debug Ruby C code. > If the salt variable is NULL then what is the IV used in this case? I need > th IV for the Scala code otherwise I cannot decrypt what the Ruby code is > encrypting. Also I found a highly related StackOverflow question on this > [2], but the solution involves not using pkcs5_keyivgen method at all and > setting a known random IV on the OpenSSL::Cipher::Cipher object so it > doesn't answer my question sadly as I am not in a position to do this > migration yet. You shouldn't require the actual key and IV used to do password-based encryption. What you would normally do on the receiving end is to go through the same steps as you did when encrypting the initial message, using the same password, salt and iterations that the encrypting party used. In Java, this would look something like ----- start source //These three need to be exactly the same as the ones used in Ruby char[] password = ... byte[] salt = ... int count = ... PBEParamterSpec params = new PBEParameterSpec(salt, count); PBEKeySpec keySpec = new PBEKeySpec(password); SecretKeyFactory keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); SecretKey key = keyFac.generateSecret(keySpec); Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES"); pbeCipher.init(Cipher.DECRYPT_MODE, key, params); //now decrypt ----- end source Figuring out what the key and iv are that were generated would sort of defeat the purpose of password-based encryption. Although not impossible, it would definitely result in a lot more work. For your migration to using PBKDF2, I just added some notes on how to use it yesterday [1]. I also gave an example on SO how we did similar upgrading of password schemes in the past [2]. It talks about moving from MD5 to bcrypt but applies to arbitrary algorithms. I hope this still helps you in the process! -Martin [1] https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl.c#L545-L606 [2] http://stackoverflow.com/questions/10771198/migrate-old-md5-passwords-to-bcrypt-passwords/10775785#10775785