FipsUnapprovedOperationError при создании сообщения CMS с помощью BouncyCastle

Я пытаюсь создать зашифрованное сообщение 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?


person Michael    schedule 02.05.2017    source источник


Ответы (1)


Пробовали ли вы настроить SecureRandom, одобренный FIPS?

CryptoServicesRegistrar.setSecureRandom(
    new FipsDRBG.Builder(
        new BasicEntropySourceProvider(new SecureRandom(), true))
    .build(FipsDRBG.SHA512_HMAC, null, false)
);

затем на вашем билдере (и везде, где он может вам понадобиться):

encryptorBuilder.setSecureRandom(CryptoServicesRegistrar.getSecureRandom());
person Kevin Herron    schedule 02.05.2017
comment
Спасибо! Добавление вызова encryptorBuilder.setSecureRandom() сработало для меня. Я уже сделал вызов CryptoServicesRegistrar.setSecureRandom(), чтобы установить там свой собственный экземпляр. Я неправильно понял, что делает эта функция, и предположил, что она установила глобальное значение по умолчанию... - person Michael; 03.05.2017