1

我正在尝试使用 bouncycastle 对任意长度的消息进行不对称加密。(1.4+ 使用 C#)

这是我现在拥有的代码。它应该(但不会)生成一条 CMS 消息,其中数据本身使用 AES256 和随机密钥进行加密,并且密钥使用来自keyPair.

keyPair是一个 RSA 密钥 (RsaKeyParameters)

public static byte[] Encrypt(byte[] input, AsymmetricCipherKeyPair keyPair)
{
    CmsEnvelopedDataGenerator generator = new CmsEnvelopedDataGenerator();

    // those two lines are certainly wrong.
    // I have no idea what the subKeyID parameter does
    byte[] subKeyId = new byte[] {};
    generator.AddKeyTransRecipient(keyPair.Public, subKeyId);

    CmsProcessableByteArray cmsByteArray = new CmsProcessableByteArray(input);
    CmsEnvelopedData envelopeData = 
      generator.Generate(cmsByteArray, CmsEnvelopedDataGenerator.Aes256Cbc);

    return envelopeData.GetEncoded();
}

方法中的subKeyId参数是Encrypt什么,它需要具有什么值?

4

3 回答 3

2

aaronls 对“用 Java 开始密码学”的作者有点不公平,毕竟他一开始就自己编写了所有的单元测试......

正如其他评论者指出的那样,CMS 使用证书,您不能只传递公钥;必须可以通过“SubjectKeyIdentifier”或“IssuerAndSerialNumber”引用密钥。AddKeyTransRecipient 的两个备选方案允许这样做。如果这些术语对您没有任何意义,您可能需要阅读 X.509 的背景知识。

于 2010-02-02T14:04:38.447 回答
0

查看 BouncyCastle 源的 EnvelopedDataTest.cs 文件中的函数 TryKekAlgorithm。他们不是在做 AddKeyTransRecipient,而是在做 AddKekRecipient。

    public static byte[] Encrypt(byte[] input, AsymmetricCipherKeyPair keyPair)
    {
        CmsEnvelopedDataGenerator generator = new CmsEnvelopedDataGenerator();
        DerObjectIdentifier algOid = //initialize

        //Still trying to figure out kekId here.
        byte[] kekId = new byte[] { 1, 2, 3, 4, 5 };
        string keyAlgorithm = ParameterUtilities.GetCanonicalAlgorithmName("AES256");

        generator.AddKekRecipient(keyAlgorithm, keyPair.Public, kekId);

        CmsProcessableByteArray cmsByteArray = new CmsProcessableByteArray(input);
        CmsEnvelopedData envelopeData =
          generator.Generate(cmsByteArray, CmsEnvelopedDataGenerator.Aes256Cbc);

        return envelopeData.GetEncoded();
    }

编辑:我认为 kekId 只是用于引用密钥的唯一标识符。只是一种“命名”密钥的方法。因此,您可以拥有一本钥匙簿,每个钥匙都有一个标识符。当您发送加密消息时,未加密的密钥标识符会告诉您使用哪个密钥来加密消息。

这是第 140 页上对密钥标识符的一个很好的解释: [ http://books.google.com/books?id=Pgg-Es2j3UEC&pg=PA140&lpg=PA140&dq=understanding+key+identifiers+encrypt&source=bl&ots=nFg0BzM2ht&sig=Ux5sreXMKyuEEZu0uaxE7cXC1VI&hl= en&ei=JKKJStbHGJivtgffsNznDA&sa=X&oi=book_result&ct=result&resnum=6#v=onepage&q=&f=false][1]

这是另一本使用 BouncyCastleCrypto 的书,但看起来他们只是抄袭了单元测试源代码。They have explained it a little: [ http://books.google.com/books?id=WLLAD2FKH3IC&pg=PA343&lpg=PA343&dq=CmsEnvelopedDataGenerator+AddKekRecipient&source=bl&ots=O9HinJm3yB&sig=K5Z99DIVWW4-0abPIFR7x4lzBhU&hl=en&ei=g6aJSrjeDuHktgennNjnDA&sa=X&oi=book_result&ct=result&resnum= 6#v=onepage&q=CmsEnvelopedDataGenerator%20AddKekRecipient&f=false][2]

于 2009-08-17T18:02:09.497 回答
0

要使用 AES,仅使用 AsymmetricCipherKeyPair 是不够的。

您应该使用 X509 证书,其中公钥由证书颁发机构 (CA) 签名。

subKeyId 是证书的一个属性,主题 Key Identifier:

       (X509Certificate) cert.getSubjectUniqueID()

要加密任意长度的消息,您应该只使用 AES 来交换对称 Keypassword 并使用此密钥进行对称加密。

于 2009-08-17T12:47:28.023 回答