0

I have a java program that I need to both generate and read AES-128-CBC encrypted RSA private keys for use in other systems. so let's say I have a file that was created by openssl with a passphrase via (password of 'bosco'):

 ssh-keygen -t rsa -b 4096

and I end up with a file like

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,0FDB737918DABC9FFF304DF7C288C659

NKZJ3qyVTtoB1jgr6muHwrMTygDipTdBQeS9B1Eal7kv2zJBNna29NvhdE4r7Maj
RWKoWsb1sroJBnf55XdTUG3NEVRvKsC8v3KuKp913kJlhRy1WKENaERbPK9hbqCu
....
-----END RSA PRIVATE KEY-----

From my understanding the value after DEK-Info: AES-128-CBC, is the vector.

I have been attempting all kinds of things to decrypt it so I can get a but I always end in errors. I've been attempting versions of this:

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.ArrayUtils;


    String bosco = "bosco";
    byte[] initVector = Hex.decodeHex("0FDB737918DABC9FFF304DF7C288C659".toCharArray());
    byte[] first8Vector = ArrayUtils.subarray(initVector, 0, 8);
    byte[] rawPassPhrase =  ArrayUtils.addAll(first8Vector, bosco.getBytes());
    byte[] passphrase = DigestUtils.md5(rawPassPhrase);
    String body = F;

    IvParameterSpec iv = new IvParameterSpec(initVector);
    SecretKeySpec skeySpec = new SecretKeySpec(passphrase, "AES");

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

    byte[] original = cipher.doFinal(Base64.decodeBase64(body));

    System.out.println("original = " + new String(original));

I did read here https://martin.kleppmann.com/2013/05/24/improving-security-of-ssh-private-keys.html about the formatting of the key (md5(first 8 bytes of vector + passphrase)

but I end up with a padding error:

javax.crypto.BadPaddingException: Given final block not properly padded

This seems way harder than it should be.

ryber
  • 4,537
  • 2
  • 26
  • 50
  • You're not really showing how you decoded/arrived at the values just that you're trying to instantiate a Cipher. Did you convert the iv from hex (doesn't look like it, at first glance)? What are you using for a key? etc – pvg Mar 31 '17 at 19:05
  • The code is rather length for stackoverflow, so rather than repeat everything just to change the cipher, please take a look at the other answer, and then ask a new clarifying question if there is a discrepancy between the algorithms that you can't work out. – erickson Mar 31 '17 at 19:12
  • It's 6 lines of code, @erickson – pvg Mar 31 '17 at 19:16
  • @pvg The code necessary to implement his solution, not the code in the question. – erickson Mar 31 '17 at 19:17
  • @erickson the question is not asking for that, it's asking about the failure of the AES decrypt, it's not a dupe. And the answer is most likely 'poster mishandled the IV'. – pvg Mar 31 '17 at 19:18
  • @erickson additionally, the answer you linked uses a completely different cipher so not useful for this key. Please remove the dupe close, it's inaccurate. – pvg Mar 31 '17 at 19:19
  • The question is how to read a private key from the OpenSSL encrypted file format. The IV is only the tip of the iceberg. If his objective is to understand a decryption error, the error would be included in the question, instead of the question that is included. The problem is identical in form to the duplicate, only the values of the parameters change. – erickson Mar 31 '17 at 19:25
  • I've updated with my latest code – ryber Mar 31 '17 at 19:49
  • 2
    @ryber The key derivation is md5(password + iv), not md5(iv + password) as it appears in your current code. – erickson Mar 31 '17 at 20:32
  • Usually [`EVP_BytesToKey`](https://wiki.openssl.org/index.php/Manual:EVP_BytesToKey(3)) is one of the issues. [Java equivalent of C++ encryption](http://stackoverflow.com/q/12920740/608639), [How to use OpenSSL generated keys in Java?](https://security.stackexchange.com/q/9600/29925), [Java openssl encryption / decryption key generation](http://stackoverflow.com/q/34502705/608639), [Password to key function compatible with OpenSSL commands?](http://stackoverflow.com/q/9488919/608639), etc – jww Apr 01 '17 at 02:59
  • @jww: openssl legacy keyfiles and enc file-encryption both use EVP_BytesToKey, but differently. The IV handling here is correct _for a keyfile_, only the key derivation is wrong as correctly noted by erickson. Though after decrypting you still need to convert PKCS1 format to a Java-acceptable format (such as PKCS8). – dave_thompson_085 Apr 01 '17 at 17:18

0 Answers0