Я пытаюсь создать зашифрованное сообщение CMS Enveloped с использованием BouncyCastle FIPS 1.0.0 для Java. Я получаю следующую ошибку, указывающую, что он пытается использовать AES для генерации случайных чисел (который не является утвержденным алгоритмом для режима FIPS).
Exception in thread "main" org.bouncycastle.crypto.fips.FipsUnapprovedOperationError: Attempt to create key with unapproved RNG: AES
at org.bouncycastle.crypto.fips.Utils.validateRandom(Unknown Source)
at org.bouncycastle.crypto.fips.Utils.validateKeyGenRandom(Unknown Source)
at org.bouncycastle.crypto.fips.FipsAES$KeyGenerator.<init>(Unknown Source)
at org.bouncycastle.crypto.fips.FipsAES$KeyGenerator.<init>(Unknown Source)
at org.bouncycastle.jcajce.provider.ProvAES$39$1.createInstance(Unknown Source)
at org.bouncycastle.jcajce.provider.BaseKeyGenerator.engineInit(Unknown Source)
at javax.crypto.KeyGenerator.init(KeyGenerator.java:510)
at org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder$CMSOutputEncryptor.<init>(Unknown Source)
at org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder.build(Unknown Source)
Во-первых, я удостоверяюсь, что BouncyCastle загружается как поставщик JCE, а затем я удостоверяюсь, что он работает только в режиме, одобренном FIPS.
if(!CryptoServicesRegistrar.isInApprovedOnlyMode()) {
CryptoServicesRegistrar.setApprovedOnlyMode(true);
}
После этого я в основном просто использую код, подобный примеру в мини-книге BC FIPS в 100 а>. Код, который у меня есть до сих пор, выглядит следующим образом:
private static final String FIPS_PROVIDER = "BCFIPS";
public byte[] encrypt(X509Certificate cert, byte[] dataToEncrypt) throws CertificateEncodingException, CMSException, IOException, InvalidAlgorithmParameterException {
CMSEnvelopedDataGenerator envelopedGen = new CMSEnvelopedDataGenerator();
JcaAlgorithmParametersConverter paramsConverter = new JcaAlgorithmParametersConverter();
AlgorithmIdentifier algId = paramsConverter.getAlgorithmIdentifier(PKCSObjectIdentifiers.id_RSAES_OAEP, OAEPParameterSpec.DEFAULT);
JceKeyTransRecipientInfoGenerator recipientInfo = new JceKeyTransRecipientInfoGenerator(cert, algId);
recipientInfo.setProvider(FIPS_PROVIDER);
envelopedGen.addRecipientInfoGenerator(recipientInfo);
CMSProcessableByteArray processableArray = new CMSProcessableByteArray(dataToEncrypt);
JceCMSContentEncryptorBuilder encryptorBuilder = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_CBC);
encryptorBuilder.setProvider(FIPS_PROVIDER);
OutputEncryptor outputEncryptor = encryptorBuilder.build();
return envelopedGen.generate(processableArray, outputEncryptor).getEncoded();
}
Если я не переведу BouncyCastle в режим только с одобрением FIPS, тогда этот код будет работать нормально, но мне нужно иметь возможность работать в этом режиме. Есть ли способ указать CMSOutputEncryptor использовать другой алгоритм RNG?