- могу конвертировать ЗАШИФРОВАННЫЙ ЗАКРЫТЫЙ ЧАСТНЫЙ КЛЮЧ -> ЧАСТНЫЙ КЛЮЧ;
- не удалось выполнить ЧАСТНЫЙ КЛЮЧ -> ЗАШИФРОВАННЫЙ ЧАСТНЫЙ КЛЮЧ – как получить правильные параметры алгоритма для PBES2?
- получить правильное имя алгоритма PBES2 в AlgorithmParameters; но тогда cipher/kdf не инициализируется в ASN.1
- получите все поля ASN.1 правильно, но SUN/SunJCE не принимает длинное имя PBEWithHmacSHA256AndAES_256; Я проследил код, и он ищет PBES2
Код: Выделить всё
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQguwofTpfqBCC6NPhF
WB5b6IfkD8C1mj2fdxyrYCCE/s+hRANCAAQLYKgHgOgGTWYDCaPO60XpdYXPYtao
nz1YtmZHooR5QOz22QM4Iwyrkky01qsDJbWaXjQDTxWDwm2nMQuiEp2M
-----END PRIVATE KEY-----
Код: Выделить всё
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIH0MF8GCSqGSIb3DQEFDTBSMDEGCSqGSIb3DQEFDDAkBBClpAgdFf+Ezj405avG
//ZgAgIIADAMBggqhkiG9w0CCQUAMB0GCWCGSAFlAwQBKgQQgic0LMiWWQ4c4ZaA
O6dMYwSBkBKZhUitcgjw3uKYWnWGDzSRHUgvgKLf73D85anZ1yMO71t/ZCX7bC29
cVECnVSgL8fvyp/JZG1HDMJzLPNnENsESipk4wFgKnIWh/vlxT5mNSY4nFO/3My4
gRzlY1XJ+AA4qflU8tb0HfMTM42dmH2+DALmMsJgplntqX/9svv7h7pfsVoMckQX
dr/OetPvsA==
-----END ENCRYPTED PRIVATE KEY-----
Код: Выделить всё
class Pbes2Test {
@Test
void canParseThisKey() {
File file = new File("src/test/resources/key-encrypted.der");
byte[] fileData = FileUtils.readFileToByteArray(file);
EncryptedPrivateKeyInfo encInfo = new EncryptedPrivateKeyInfo(fileData);
assertEquals("PBEWithHmacSHA256AndAES_256", encInfo.getAlgName())
// so KDF is PBKDF2 and cipher is AES-256-CBC
byte[] cipherText = encInfo.getEncryptedData();
// get: salt, iv, iterationCount
AlgorithmParameters algParameters = encInfo.getAlgParameters();
var paramSpec = algParameters.getParameterSpec(PBEParameterSpec.class);
AlgorithmParameterSpec ivSpec = paramSpec.getParameterSpec();
PBEKeySpec spec = new PBEKeySpec("something".toCharArray(),
paramSpec.getSalt(),
paramSpec.getIterationCount(),
32 * 8);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
SecretKey myKey = skf.generateSecret(spec);
byte[] myKeyData = myKey.getEncoded();
SecretKeySpec keySpec = new SecretKeySpec(myKeyData, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
cipher.update(cipherText);
cipher.doFinal();
System.out.println("Profit!!");
}
@Test
void cannnotCreateEncryptedPKCS8DER() throws Exception {
IvParameterSpec ivSpec;
PBEParameterSpec paramSpec;
PBEKeySpec pbeKeySpec;
File file = new File("src/test/resources/key-plain.der");
byte[] plaintext = FileUtils.readFileToByteArray(file);
byte[] salt = new byte[16];
byte[] iv = new byte[16];
SecureRandom random = new SecureRandom();
int iterationCount = 2048;
random.nextBytes(salt);
random.nextBytes(iv);
ivSpec = new IvParameterSpec(iv);
// ---- do cryptography
pbeKeySpec = new PBEKeySpec("something".toCharArray(),
salt,
iterationCount,
32 * 8);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
SecretKey myKey = skf.generateSecret(pbeKeySpec);
byte[] myKeyData = myKey.getEncoded();
SecretKeySpec keySpec = new SecretKeySpec(myKeyData, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
buf.write(cipher.update(plaintext));
buf.write(cipher.doFinal());
buf.close();
System.out.printf("Successfully created encryptedData!! size = %d\n", buf.size());
// ---- ASN.1
EncryptedPrivateKeyInfo encryptedPrivateKey;
File file2;
// Take 1: this looks wrong; where is AES-256-CBC, PBKDF2 added to the AlgorithmParameters?
AlgorithmParameters outputParameters = AlgorithmParameters.getInstance("PBES2");
paramSpec = new PBEParameterSpec(salt, iterationCount, ivSpec);
outputParameters.init(paramSpec);
// FAIL: Cipher AES-256-CBC, KDF PBKDF2 not initialized
encryptedPrivateKey = new EncryptedPrivateKeyInfo(outputParameters, buf.toByteArray());
file2 = new File("test-output/TEST-key-encrypted.der");
FileUtils.writeByteArrayToFile(file2, encryptedPrivateKey.getEncoded());
// Take 2: this almost works but has the wrong name!
AlgorithmParameters outputParameters = AlgorithmParameters.getInstance("PBEWithHmacSHA256AndAES_256");
paramSpec = new PBEParameterSpec(salt, iterationCount, ivSpec);
outputParameters.init(paramSpec);
// FAIL: constructor only accepts "PBES2" and not "PBEWithHmacSHA256AndAES"
encryptedPrivateKey = new EncryptedPrivateKeyInfo(outputParameters, buf.toByteArray());
file2 = new File("test-output/TEST-key-encrypted.der");
FileUtils.writeByteArrayToFile(file2, encryptedPrivateKey.getEncoded());
}
}
Код: Выделить всё
java.lang.NullPointerException: Cannot invoke "sun.security.util.ObjectIdentifier.encode(sun.security.util.DerOutputStream)" because "oid" is null
at java.base/sun.security.util.DerOutputStream.putOID(DerOutputStream.java:317)
at java.base/com.sun.crypto.provider.PBES2Parameters.engineGetEncoded(PBES2Parameters.java:378)
at java.base/java.security.AlgorithmParameters.getEncoded(AlgorithmParameters.java:380)
at java.base/sun.security.x509.AlgorithmId.(AlgorithmId.java:111)
at java.base/sun.security.x509.AlgorithmId.get(AlgorithmId.java:480)
at java.base/javax.crypto.EncryptedPrivateKeyInfo.(EncryptedPrivateKeyInfo.java:191)
at integration.keystore.OpenSSLTest.foStackExchage(OpenSSLTest.java:278)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
DerOutputStream encryptionScheme = new DerOutputStream();
// algorithm is id-aes128-CBC or id-aes256-CBC
encryptionScheme.putOID(cipherAlgo_OID);
Код: Выделить всё
java.security.NoSuchAlgorithmException: unrecognized algorithm name: PBEWithHmacSHA256AndAES_256
at java.base/sun.security.x509.AlgorithmId.get(AlgorithmId.java:477)
at java.base/javax.crypto.EncryptedPrivateKeyInfo.(EncryptedPrivateKeyInfo.java:191)
at integration.keystore.OpenSSLTest.foStackExchange(OpenSSLTest.java:278)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
- IAIK имеет спецификацию PBES2ParametersSpec: https://javadoc.sic.tech/iaik_jce /current/iaik/pkcs/pkcs5/PBES2ParameterSpec.html
- BouncyCastle имеет PBES2Parameters: https://downloads.bouncycastle.org/java ... on-javadoc /org/bouncycastle/asn1/pkcs/PBES2Parameters.html
Подробнее здесь: https://stackoverflow.com/questions/790 ... rypted-key