Как зашифровать значение CMS EnvelopedData с помощью AES-GCM с помощью BouncyCastle? - PullRequest
0 голосов
/ 27 марта 2020

Я могу сгенерировать действительное значение CMS EnvelopedData с помощью AES-CB C, используя приведенный ниже код Kotlin:

import org.bouncycastle.cert.X509CertificateHolder
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
import org.bouncycastle.cms.CMSAlgorithm
import org.bouncycastle.cms.CMSEnvelopedDataGenerator
import org.bouncycastle.cms.CMSProcessableByteArray
import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder
import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator

fun encrypt(plaintext: ByteArray, recipientCertificate: X509CertificateHolder): ByteArray {
    val cmsEnvelopedDataGenerator = CMSEnvelopedDataGenerator()

    val x509Certificate = JcaX509CertificateConverter()
        .getCertificate(recipientCertificate)
    val transKeyGen =
        JceKeyTransRecipientInfoGenerator(x509Certificate)
    cmsEnvelopedDataGenerator.addRecipientInfoGenerator(transKeyGen)

    val msg = CMSProcessableByteArray(plaintext)
    val encryptor = JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).build()
    val bcEnvelopedData = cmsEnvelopedDataGenerator.generate(msg, encryptor)
    return bcEnvelopedData.encoded
}

Но если я заменю CMSAlgorithm.AES128_CBC на CMSAlgorithm.AES128_GCM, JceCMSContentEncryptorBuilder.build() выдает следующую ошибку:

cannot create key generator: 2.16.840.1.101.3.4.1.6 KeyGenerator not available

Эта ошибка, по-видимому, указывает на то, что AES-GCM-128 не поддерживается, но тот факт, что объект CMSAlgorithm.AES128_GCM существует, подсказывает мне, что это не может быть - я должно быть, делаю что-то не так. Может быть, IV не сгенерирован за кулисами для меня, и я должен как-то установить его явно?

Я использую org.bouncycastle:bcpkix-jdk15on:1.64.

ОБНОВЛЕНИЕ: Я нашел тест в наборе тестов BouncyCastle, который использует AES-GCM в значениях EnvelopedData, и они также передают CMSAlgorithm.AES128_GCM в JceCMSContentEncryptorBuilder таким же образом. Разница лишь в том, что они звонят .setProvider("BC") до .build(), но я только что попробовал, и это не имело никакого значения.

1 Ответ

0 голосов
/ 27 марта 2020

Отвечая на мой вопрос:

JceCMSContentEncryptorBuilder.setProvider() обязательно должен быть вызван до .build(), но если провайдер не зарегистрирован, вы должны передать экземпляр org.bouncycastle.jce.provider.BouncyCastleProvider.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...