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.