使用BouncyCastle

时间:2017-05-02 21:02:14

标签: java encryption bouncycastle fips

我正在尝试使用BouncyCastle FIPS 1.0.0 for Java创建CMS Enveloped加密消息。我收到以下错误,表明它正在尝试使用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 in 100 mini-book中的示例代码。我到目前为止的代码如下:

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算法?

1 个答案:

答案 0 :(得分:3)

您是否尝试过设置FIPS认可的SecureRandom?

Popen()

然后在您的构建器上(以及您可能需要的任何其他地方):

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