代码之家  ›  专栏  ›  技术社区  ›  levinalex

BouncyCastle:addKeyTransRecipient的subKeyID参数是什么?

  •  1
  • levinalex  · 技术社区  · 15 年前

    我试图用bouncycastle不对称地加密任意长度的消息。(1.4+C)

    这就是我现在拥有的代码。它应该(但不)生成一个CMS消息,其中数据本身使用一个随机密钥用AES256加密,密钥使用来自的公钥加密。 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 方法和它需要有什么值?

    3 回复  |  直到 15 年前
        1
  •  0
  •   AaronLS    15 年前

    查看bouncycastle源的enveleddatatest.cs文件中的函数trykekAlgorithm。他们不是做addkeyrecipient,而是做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]

        2
  •  2
  •   Peter Dettman    15 年前

    阿伦斯对“开始用Java加密”的作者来说有点不公平,毕竟他首先编写了所有的单元测试。

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

        3
  •  0
  •   mancereus    15 年前

    要使用AES,使用非对称密钥对是不够的。

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

    SubkeyID是证书的一个属性,主题密钥标识符:

           (X509Certificate) cert.getSubjectUniqueID()
    

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