经过艰难的无数个小时后,我终于得到了当前的工作代码,使用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?
答案 0 :(得分:0)
请注意,我不确定这是否适用于所有国家/地区/所有客户。
如果你想删除限制,你可以使用一些反射魔法。这就是我在我的框架中所做的工作(部分取自: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示例,它对我帮助很大。