我有一个java程序,我需要生成和读取AES-128-CBC加密的RSA私钥,以便在其他系统中使用。所以,假设我有一个由openssl创建的文件,密码为'bosco'密码:
ssh-keygen -t rsa -b 4096
我最终得到了像
这样的文件-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,0FDB737918DABC9FFF304DF7C288C659
NKZJ3qyVTtoB1jgr6muHwrMTygDipTdBQeS9B1Eal7kv2zJBNna29NvhdE4r7Maj
RWKoWsb1sroJBnf55XdTUG3NEVRvKsC8v3KuKp913kJlhRy1WKENaERbPK9hbqCu
....
-----END RSA PRIVATE KEY-----
根据我的理解,DEK-Info:AES-128-CBC之后的值是矢量。
我一直在尝试各种各样的东西来解密它,所以我可以得到一个,但我总是以错误结束。我一直在尝试这个版本:
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));
我在这里读到了https://martin.kleppmann.com/2013/05/24/improving-security-of-ssh-private-keys.html关于密钥格式化的信息(md5(向量的第8个字节+密码)
但最终出现了填充错误:
javax.crypto.BadPaddingException: Given final block not properly padded
这似乎比应该更难。