How to use BouncyCastle lightwigth API to generate cms enveloped data

柔情痞子 提交于 2020-01-03 05:16:11

问题


After struggling uncountable hours I finally have the current working code to generate CMS enveloped (RSA-OAEP / PKCS#1) data with recipient info using JCE/JCA:

String digest = "SHA-256";
String mgfDigest = "SHA-256";

// Data to encrypt
CMSTypedData msg = new CMSProcessableByteArray(data);

// Generator for my CMS enveloped data 
CMSEnvelopedDataGenerator envelopedDataGen = new CMSEnvelopedDataGenerator();

// Recipient Info Stuff
JcaAlgorithmParametersConverter paramsConverter = new JcaAlgorithmParametersConverter();
OAEPParameterSpec oaepSpec = new OAEPParameterSpec(digest, "MGF1", new MGF1ParameterSpec(mgfDigest), PSource.PSpecified.DEFAULT);
AlgorithmIdentifier oaepAlgId = paramsConverter.getAlgorithmIdentifier(PKCSObjectIdentifiers.id_RSAES_OAEP, oaepSpec);
envelopedDataGen.addRecipientInfoGenerator(
        new JceKeyTransRecipientInfoGenerator(
                getCert(), 
                oaepAlgId).setProvider("BC"));

/*
  * Generate CMS-Data
  * CMSOutputEncryptor is my own Class implementing OutputEncryptor
  */
CMSEnvelopedData ed = envelopedDataGen.generate(
        msg, 
        new CMSOutputEncryptor());

byte[] encoded = ed.getEncoded();

This works as expected but because it uses JCE my customers need to install the unlimited strength api to use this code. I would prefer a way to overcome these needs because most of my customers fingers are thumbs...

Maybe someone can show me a piece of code which use a pure BouncyCastle way of doing the same so that one don't need to install the unlimited strength api?


回答1:


Please note that I am not sure if this is legal in all countries / for all customers.

If you want to remove the restriction, you can work with some reflection magic. This is how I do it in my framework (Partially taken from: https://github.com/jruby/jruby/blob/0c345e1b186bd457ebd96143c0816abe93b18fdf/core/src/main/java/org/jruby/util/SecurityHelper.java):

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;

public class UnlimitedStrengthHelper {

    public static void removeCryptoStrengthRestriction() {
        try {
            if (Cipher.getMaxAllowedKeyLength("AES") < 256) {
                Class jceSecurity = Class.forName("javax.crypto.JceSecurity");
                Field isRestricted = jceSecurity.getDeclaredField("isRestricted");
                if (Modifier.isFinal(isRestricted.getModifiers())) {
                    Field modifiers = Field.class.getDeclaredField("modifiers");
                    modifiers.setAccessible(true);
                    modifiers.setInt(isRestricted, isRestricted.getModifiers() & ~Modifier.FINAL);
                    modifiers.setAccessible(false);
                }
                isRestricted.setAccessible(true);
                isRestricted.setBoolean(null, false);
                isRestricted.setAccessible(false);
            }
        } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException
                | NoSuchAlgorithmException | NoSuchFieldException | SecurityException ex) {
            System.out.println("It is not possible to use unrestricted policy with this JDK, "
                    + "consider reconfiguration: " + ex.getLocalizedMessage());
        }
    }
}

The code first checks whether the restriction exists (in that case, you cannot work with AES256). Afterwards, it takes the JceSecurity class and its isRestricted field. It ensures that we can access this field and finally sets its value to false.

Btw., thank you for your CMS example, it helped me a lot.



来源:https://stackoverflow.com/questions/38686704/how-to-use-bouncycastle-lightwigth-api-to-generate-cms-enveloped-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!