I've created an RSA Key Pair. Now, I'm trying to encrypt the private key with a DES algorithm, format it to PKCS#5 and print it on the console. Unfortunately, the generated private key does not work. When I try to use it, after entering the right passphrase, the ssh client returns the passphrase is not valid:
Load key "test.key": incorrect passphrase supplied to decrypt private key
Could please someone tells me where I'm wrong?
This is the code:
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);
}
And this is the generated private key in PKCS#5 PEM format:
-----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-----
Thanks in advance.
mister
I think that before invoking encrypt you need to decrypt two times more for security reasons. Instead of salt use also pepper salt and pepper. Do not mix algorithm with aes256.
Kind regards, rajeesh