我创建了一个 RSA 密钥对。现在,我正在尝试使用 DES 算法加密私钥,将其格式化为 PKCS#5 并在控制台上打印。不幸的是,生成的私钥不起作用。当我尝试使用它时,输入正确的密码后,ssh客户端返回密码无效:
加载密钥“test.key”:为解密私钥提供的密码不正确
可以请有人告诉我我错在哪里吗?
这是代码:
private byte[] iv;
public void generate() throws Exception {
RSAKeyPairGenerator generator = new RSAKeyPairGenerator();
generator.initialize(2048);
KeyPair keyPair = generator.generateKeyPair();
String passphrase = "passphrase";
byte[] encryptedData = encrypt(keyPair.getPrivate().getEncoded(), passphrase);
System.out.println(getPrivateKeyPem(Base64.encodeBase64String(encryptedData)));
}
private byte[] encrypt(byte[] data, String passphrase) throws Exception {
String algorithm = "PBEWithMD5AndDES";
salt = new byte[8];
int iterations = 1024;
// Create a key from the supplied passphrase.
KeySpec ks = new PBEKeySpec(passphrase.toCharArray());
SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithm);
SecretKey key = skf.generateSecret(ks);
// Create the salt from eight bytes of the digest of P || M.
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(passphrase.getBytes());
md.update(data);
byte[] digest = md.digest();
System.arraycopy(digest, 0, salt, 0, 8);
AlgorithmParameterSpec aps = new PBEParameterSpec(salt, iterations);
Cipher cipher = Cipher.getInstance(AlgorithmID.pbeWithSHAAnd3_KeyTripleDES_CBC.getJcaStandardName());
cipher.init(Cipher.ENCRYPT_MODE, key, aps);
iv = cipher.getIV();
byte[] output = cipher.doFinal(data);
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(salt);
out.write(output);
out.close();
return out.toByteArray();
}
private String getPrivateKeyPem(String privateKey) throws Exception {
StringBuffer formatted = new StringBuffer();
formatted.append("-----BEGIN RSA PRIVATE KEY----- " + LINE_SEPARATOR);
formatted.append("Proc-Type: 4,ENCRYPTED" + LINE_SEPARATOR);
formatted.append("DEK-Info: DES-EDE3-CBC,");
formatted.append(bytesToHex(iv));
formatted.append(LINE_SEPARATOR);
formatted.append(LINE_SEPARATOR);
Arrays.stream(privateKey.split("(?<=\\G.{64})")).forEach(line -> formatted.append(line + LINE_SEPARATOR));
formatted.append("-----END RSA PRIVATE KEY-----");
return formatted.toString();
}
private String bytesToHex(byte[] bytes) {
char[] hexArray = "0123456789ABCDEF".toCharArray();
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
这是生成的 PKCS#5 PEM 格式的私钥:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,CA138D5D3C048EBD
+aZNZJKLvNtlmnkg+rFK6NFm45pQJNnJB9ddQ3Rc5Ak0C/Igm9EqHoOS+iy+PPjx
pEKbhc4Qe3U0GOT9L5oN7iaWL82gUznRLRyUXtOrGcpE7TyrE+rydD9BsslJPCe+
y7a9LnSNZuJpJPnJCeKwzy5FGVv2KmDzGTcs9IqCMKgV69qf83pOJU6Dk+bvh9YP
3I05FHeaQYQk8c3t3onfljVIaYOfbNYFLZgNgGtPzFD4OpuDypei/61i3DeXyFUA
SNSY5fPwp6iSeSKtwduSEJMX31TKSpqWeZmEmMNcnh8oZz2E0jRWkbkaFuZfNtqt
aVpLN49oRpbsij+i1+udyuIXdBGRYt9iDZKnw+LDjC3X9R2ceq4AOdfsmEVYbO1i
YNms9eXSkANuchiI2YqkKsCwqI5S8S/2Xj76zf+pCDhCTYGV3RygkN6imX/Qg2eF
LOricZZTF/YPcKnggqNrZy4KSUzAgZ9NhzWCWOCiGFcQLYIo+qDoJ8t4FwxQYhx9
7ckzXML0n0q5ba5pGekLbBUJ9/TdtnqfqmYrHX+4OlrR7XAu478v2QH6/QtNKdZf
VRTqmKKH0n8JL9AgaXWipQstW5ERNZJ9YPBASQzewVNLv4gRZRTw8bYcU/hiPbWp
eqULYYI9324RzY3UTsz3N9X+zQsT02zNdxud7XmmoHL493yyvqT9ERmF4uckGYei
HZ16KFeKQXE9z+x0WNFAKX3nbttVlN5O7TAmUolFTwu11UDsJEjrYMZRwjheAZyD
UnV1LwhFT+QA0r68Mto3poxpAawCJqPP50V4jbhsOb0J7sxT8fo2mBVSxTdb9+t1
lG++x/gHcK51ApK1tF1FhRRKdtOzSib376Kmt23q0jVDNVyy09ys+8LRElOAY1Es
LIuMMM3F7l+F4+knKh3/IkPZwRIz3f9fpsVYIePPS1bUdagzNoMqUkTwzmq6vmUP
C5QvN6Z5ukVCObK+T8C4rya8KQ/2kwoSCRDIX6Mzpnqx6SoO4mvtBHvPcICGdOD6
aX/SbLd9J2lenTxnaAvxWW0jkF6q9x9AAIDdXTd9B5LnOG0Nq+zI+6THL+YpBCB9
6oMO4YChFNoEx0HZVdOc8E7xvXU2NqinmRnyh7hCR5KNfzsNdxg1d8ly67gdZQ1Q
bk1HPKvr6T568Ztapz1J/O6YWRIHdrGyA6liOKdArhhSI9xdk3H3JFNiuH+qkSCB
0mBYdS0BVRVdKbKcrk4WRHZxHsDsQn1/bPxok4dCG/dGO/gT0QlxV+hOV8h/4dJO
mcUvzdW4I8XKrX5KlTGNusVRiFX3Cy8FFZQtSxdWzr6XR6u0bUKS+KjDl1KoFxPH
GwYSTkJVE+fbjsSisQwXjWnwGGkNDuQ1IIMJOAHMK4Mly1jMdFF938WNY7NS4bIb
IXXkRdwxhdkRDiENSMXY8YeCNBJMjqdXZtR4cwGEXO+G+fpT5+ZrfPbQYO+0E0r4
wGPKlrpeeR74ALiaUemUYVIdw0ezlGvdhul2KZx4L82NpI6/JQ7shq9/BEW2dWhN
aDuWri2obsNL3kk2VBWPNiE6Rn/HtjwKn7ioWZ3IIgOgyavcITPBe0FAjxmfRs5w
VWLFBXqcyV9cu1xS4GoCNLk0MrVziUCwHmwkLIzQZos=
-----END RSA PRIVATE KEY-----
提前致谢。