Преобразовать закрытый ключ в формате 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);
Другие вопросы по тегам