Преобразовать закрытый ключ в формате PKCS#1 в закрытый ключ в формате PKCS#8 с помощью java
У меня есть закрытый ключ в формате PKCS#1 (сгенерированный opendkim-genkey) вот так
-----BEGIN RSA PRIVATE KEY-----
Base64 encoded data
-----END RSA PRIVATE KEY-----
Теперь я должен использовать его в Java для генерации java.security.PrivateKey
Но Java поддерживает только закрытый ключ в формате PKCS#8.
Я знаю, что есть способ конвертировать из PKCS#8 в PKCS#1 с помощью Java (используя Bouncycastle), но есть ли способ конвертировать из PKCS#1 в PKCS#8 с помощью Java?
2 ответа
Отказ от ответственности: я сам не придумал это решение, оно было написано Маркоскоттрайтом в github. Найти оригинальный код здесь
Вы можете сделать это с помощью BouncyCastle, если у вас есть PrivateKey k
объект.
try (ASN1InputStream asn1InputStream = new ASN1InputStream(k.getEncoded()))
{
DERObject rsaPrivateKey = asn1InputStream.readObject();
return new PrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption), rsaPrivateKey).getDEREncoded();
}
Преобразование закрытого ключа RSA, закодированного в PKCS#1, в PKCS#8, который можно использовать с помощью vanilla Java, возможно с помощью библиотеки bcprov от Bouncy Castle.
Поскольку разница между PKCS#1 и PKCS#8 заключается просто в ведущем PrivateKeyAlgorithmIdentifier, мы можем добавить это, чтобы получить PKCS#8:
byte[] pkcs1Encoded = ...;
AlgorithmIdentifier algId = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
PrivateKeyInfo privateKeyInfo = new PrivateKeyInfo(algId, ASN1Sequence.getInstance(pkcs1Encoded));
byte[] pkcs8Encoded = privateKeyInfo.getEncoded();
Затем это используется ванильной Java:
java.security.spec.KeySpec spec = new java.security.spec.PKCS8EncodedKeySpec(pkcs8Encoded);
java.security.KeyFactory.getInstance("RSA").generatePrivate(spec);
Однако, если вы все равно используете Bouncy Castle, вы можете использовать их провайдера, и вам не нужно явно преобразовывать PKCS#1 в PKCS#8, поскольку их KeyFactorySpi может потреблятьPKCS8EncodedKeySpec
с засунутым в него PKCS#1.
например:
java.security.spec.KeySpec spec = new java.security.spec.PKCS8EncodedKeySpec(pkcs1Encoded);
java.security.KeyFactory.getInstance("RSA", new BouncyCastleProvider()).generatePrivate(spec);
Провайдер Bouncy Castle также может быть зарегистрирован по всему миру:
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
...
java.security.spec.KeySpec spec = new java.security.spec.PKCS8EncodedKeySpec(pkcs1Encoded);
java.security.KeyFactory.getInstance("RSA").generatePrivate(spec);