Bouncycastle:AddKeyTransRecipient的subKeyID-Parameter有什么作用?

时间:2009-08-10 10:15:23

标签: c# encryption cryptography rsa bouncycastle

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

这是我现在的代码。它应该(但不是)生成CMS消息,其中数据本身使用带有随机密钥的AES256加密,密钥使用来自keyPair的公钥加密。

keyPair是RSA-Key(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参数是什么?它需要具有什么价值?

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

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

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

subKeyId是证书的属性,主题密钥标识符:

       (X509Certificate) cert.getSubjectUniqueID()

要加密艺术长度的消息,您应该仅使用AES来交换对称密钥密码,并使用此密钥进行对称加密。

答案 2 :(得分: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的书,但看起来他们只是扯掉了单元测试源代码。他们解释了一下: [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]