当前位置: 首页 > 知识库问答 >
问题:

Bouncy Castle CMS公钥加密

萧献
2023-03-14

我遵循以下示例:http://www.baeldung.com/java-bouncy-castle

我有几个问题:

public static byte[] encryptData(byte[] data,
  X509Certificate encryptionCertificate)
  throws CertificateEncodingException, CMSException, IOException {

    byte[] encryptedData = null;
    if (null != data && null != encryptionCertificate) {
        CMSEnvelopedDataGenerator cmsEnvelopedDataGenerator
          = new CMSEnvelopedDataGenerator();

        JceKeyTransRecipientInfoGenerator jceKey 
          = new JceKeyTransRecipientInfoGenerator(encryptionCertificate);
        cmsEnvelopedDataGenerator.addRecipientInfoGenerator(transKeyGen);
        CMSTypedData msg = new CMSProcessableByteArray(data);
        OutputEncryptor encryptor
          = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC)
          .setProvider("BC").build();
        CMSEnvelopedData cmsEnvelopedData = cmsEnvelopedDataGenerator
          .generate(msg,encryptor);
        encryptedData = cmsEnvelopedData.getEncoded();
    }
    return encryptedData;
}

将此应用到我的真实场景中,我只有收件人的RSA公钥,而不是整个X509Certificate。我四处打探了一下,但我不确定我该怎么做。有可能吗?

另一件事是我看到JceCMSEncryptorBuilder接受了一个ASN1Objectidentifier。我们目前正在使用这样的方法:

KeyGenerator cryptKeyGenerator = KeyGenerator.getInstance("AES", "BC");
cryptKeyGenerator.init(256);
Key encryptionKey = cryptKeyGenerator.generateKey();
Cipher symmetricCipher = Cipher.getInstance("AES/CTS/NoPadding", "BC");
symmetricCipher.init(Cipher.ENCRYPT_MODE, encryptionKey, new IvParameterSpec(ivBytes));

在CMSAlgorithm类中,我没有看到任何CTS选项。是我错过了什么,还是有办法继续使用CTS?

共有1个答案

寿意远
2023-03-14

我只有收件人的RSA公钥,而不是整个X509Certificate

CMS EnvelopedData的KeyTransRecipientInfo结构可以使用有时出现在X.509/PKIX证书中的SubjectKeyIdentifier值作为扩展,在这种情况下,Bouncy有一个重载的ctor。由于您没有证书,您必须找出使用了什么方法来计算证书中的值如果收件人将使用证书,或者尝试不同的猜测,直到您找到一个可行的,或者如果您控制收件人,只需选择一些它(他们)将接受的值。

X509ExtensionUtils及其两个子类提供了计算两种标准方案的方法,但我发现它们并不比直接进行更方便。

我们当前使用的是...AES/CTS/NOPADDING...而在CMSAlgorithm类中我没有看到任何CTS选项

这不仅仅是CMSalgorithm中的内容。有两个相关因素:

>

  • CMS/PKCS7包络数据中使用的任何特定密码(在JCA术语中为转换)必须由OID和条件参数标识

    用于给定邮件的密码必须由发件人和收件人或所有收件人支持。

    cmsalgorithm只是一个方便的密码和其他一些东西(如密钥协议)的简编,它们都具有标准化的OID,并且由BC实现,后者实际上由org.bouncycastle.cms.jcajce.EnvelopedDataHelper或BC本机等价物控制,您可以看到,该等价物只支持所支持的分组密码的CBC模式。(两者都支持RC4,但作为流密码,它不使用任何模式。另外,RC4现在非常不受欢迎。)

    我不记得在CTS模式下看到过任何一个密码的标准化OID。如果这是正确的,您就必须分配一个OID,而且由于没有其他人将实现该OID,您的消息将不能与任何人互操作。如果您可以找到您的对等体实现的标准OID(或至少AlgId),那么对于BC而言,您必须创建符合(interface)outputencryptor的自己的类,如果您有底层密码的提供者或BC本机实现,那么如果查看上面的源代码,这并不是那么复杂。

  •  类似资料:
    • 我的Android应用程序实现了RSA加密,但后端无法解密应用程序生成的令牌。这是代码,公钥的开始行和结束行在调用之前都被删除了,会有什么问题吗? 后端团队提供了以下可以工作的示例代码,但它是针对桌面Java的。Android库没有base64.getEncoder方法。这和我写的非常相似,但我的就是不起作用。 我比较了每一步的字节数组值。桌面密码和android密码得到的输入完全相同。然而,来自

    • 并且我将这个函数称为用RSA公钥加密DSA密钥的函数:

    • 问题内容: 我正在编写一个用于传输文件的小型应用程序,或多或少地将其作为一种学习更多编程加密基础的方法。这个想法是生成一个RSA密钥对,交换公共密钥,并发送AES iv和密钥以进一步解密。我想用接收者的RSA公钥加密AES密钥,如下所示: 然后,我将密钥值写给接收器,并按如下方式解密: 在控制台的另一端,我将其作为输出: 此外,如果我创建一个大小为16的字节数组,并将cipher.doFinal(

    • 说明 微信支付-获取RSA加密公钥SDK,企业付款到银行卡接口需要。 你还需要执行openssl rsa -RSAPublicKey_in -in weixin-rsa-public.pem -pubout 将命令行输出的证书内容覆盖到weixin-rsa-public.pem文件中才可使用 官方文档:https://pay.weixin.qq.com/wiki/doc/api/tools/mch

    • 在SpringBoot中有一个“rest-server” 服务在某个地方安装了许多Java中的“rest-clients”。我不控制它。 “rest-server”为每个(!)生成公钥/私钥对客户端并与客户端共享pub密钥 每个“Rest-Client”生成自己的公钥/私钥对,并与“Rest-Server”共享公钥。客户端共享其公钥和唯一ID。 “Rest-Clients”不时轮询“”Rest-S

    • 我想这个问题不是上当,所以我会试着解释一下我的情况。 我正在测试JWT,更具体地说是来自Github的JOSE-JWT lib,但是我遇到了一些麻烦。 我使用PHP和PHPSeclib生成一个私钥-公钥对,并将公钥发送给客户机。一切都是正确的,正如你在那里看到的。我的客户机接收JSON并将其转换为对象,然后使用JSON.NET将其提取为字符串。 还有弹力城堡: 例外情况: CreateToken方