如何使用BouncyCastle lightwigth API生成cms封装数据

经过艰难的无数个小时后,我终于得到了当前的工作代码,使用JCE / JCA生成带有收件人信息的CMS封装(RSA-OAEP / PKCS#1)数据:

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(); 

这可以按预期工作,但因为它使用JCE,我的客户需要安装无限强度api才能使用此代码。 我更愿意采用一种方法来克服这些需求,因为我的大多数客户手指都是拇指……

也许有人可以给我看一段代码,它使用纯粹的BouncyCastle方法做同样的事情,这样一个人不需要安装无限的力量api?

请注意,我不确定这是否适用于所有国家/地区/所有客户。

如果你想删除限制,你可以使用一些reflection魔法。 这就是我在我的框架中的做法(部分取自: 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()); } } } 

代码首先检查是否存在限制(在这种情况下,您无法使用AES256)。 之后,它将获取JceSecurity类及其isRestricted字段。 它确保我们可以访问此字段并最终将其值设置为false。

顺便说一句,谢谢您的CMS示例,它对我帮助很大。