【问题标题】:Encryption/Decryption with bouncycastle-java and RSAES-OAEP使用 bouncycastle-java 和 RSAES-OAEP 进行加密/解密
【发布时间】:2021-03-22 21:29:17
【问题描述】:

我不是加密专家,但我正在尝试使用 bouncycastle 1.67 创建一个CMSEnvelopedDataGenerator,其中会话密钥使用 RSAES-OAEP 加密( 1.2.840.113549.1.1.7)

目前我的代码如下所示:

 CMSEnvelopedDataGenerator envelopedGenerator = new CMSEnvelopedDataGenerator();
 
 JcaAlgorithmParametersConverter paramsConverter = new JcaAlgorithmParametersConverter();
 OAEPParameterSpec oaepSpec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT);

 AlgorithmIdentifier algorithmIdentifier;    
 algorithmIdentifier = paramsConverter.getAlgorithmIdentifier(PKCSObjectIdentifiers.id_RSAES_OAEP, oaepSpec);
 JceKeyTransRecipientInfoGenerator recipent = new JceKeyTransRecipientInfoGenerator(receiverCert, algorithmIdentifier).setProvider("BC");    
 
 # encrypt
 CMSEnvelopedData envelopedData;
 envelopedData = envelopedGenerator.generate(
     new CMSProcessableByteArray(encodedSignedData),  
     new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_CBC).setProvider("BC").build()
 )

它通过了,但是当我通过 openssl asn1parse 检查它时,我看到了

115:d=6  hl=2 l=   9 prim: OBJECT            :rsaesOaep
126:d=6  hl=2 l=  47 cons: SEQUENCE
128:d=7  hl=2 l=  15 cons: cont [ 0 ]
130:d=8  hl=2 l=  13 cons: SEQUENCE
132:d=9  hl=2 l=   9 prim: OBJECT            :sha256
143:d=9  hl=2 l=   0 prim: NULL
145:d=7  hl=2 l=  28 cons: cont [ 1 ]
147:d=8  hl=2 l=  26 cons: SEQUENCE
149:d=9  hl=2 l=   9 prim: OBJECT            :mgf1
160:d=9  hl=2 l=  13 cons: SEQUENCE
162:d=10 hl=2 l=   9 prim: OBJECT            :sha256

然后是十六进制转储。 在我的参考文件上是这样的:

115:d=6  hl=2 l=   9 prim: OBJECT            :rsaesOaep
126:d=6  hl=2 l=  43 cons: SEQUENCE
128:d=7  hl=2 l=  13 cons: cont [ 0 ]
130:d=8  hl=2 l=  11 cons: SEQUENCE
132:d=9  hl=2 l=   9 prim: OBJECT            :sha256
143:d=7  hl=2 l=  26 cons: cont [ 1 ]
145:d=8  hl=2 l=  24 cons: SEQUENCE
147:d=9  hl=2 l=   9 prim: OBJECT            :mgf1
158:d=9  hl=2 l=  11 cons: SEQUENCE
160:d=10 hl=2 l=   9 prim: OBJECT            :sha256

在我的文件的第 143 行是一行

143:d=9  hl=2 l=   0 prim: NULL

我不确定这是从哪里来的。

当我使用适用于我的参考文件的解密代码时,我遇到以下异常

 exception unwrapping key: bad padding: unable to decrypt block

Caused by: org.bouncycastle.cms.CMSException: exception unwrapping key: bad padding: unable to decrypt block
 at org.bouncycastle.cms.jcajce.JceKeyTransRecipient.extractSecretKey(Unknown Source)
 at org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient.getRecipientOperator(Unknown Source)
 at org.bouncycastle.cms.KeyTransRecipientInformation.getRecipientOperator(Unknown Source)
 at org.bouncycastle.cms.RecipientInformation.getContentStream(Unknown Source)

Caused by: org.bouncycastle.operator.OperatorException: bad padding: unable to decrypt block
at org.bouncycastle.operator.jcajce.JceAsymmetricKeyUnwrapper.generateUnwrappedKey(Unknown Source)

Caused by: org.bouncycastle.jcajce.provider.util.BadBlockException: unable to decrypt block
at org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.getOutput(Unknown Source)
at org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(Cipher.java:2168)

Caused by: org.bouncycastle.crypto.InvalidCipherTextException: data wrong
at org.bouncycastle.crypto.encodings.OAEPEncoding.decodeBlock(Unknown Source)
at org.bouncycastle.crypto.encodings.OAEPEncoding.processBlock(Unknown Source)

我希望它不多,那是缺失的。

编辑:

我错误生成的文件recipient.getKeyEncryptionAlgorithm().getParameters() 导致

[[0][2.16.840.1.101.3.4.2.1, NULL], [1][1.2.840.113549.1.1.8, [2.16.840.1.101.3.4.2.1, NULL]]]

正确的文件

[[0][2.16.840.1.101.3.4.2.1], [1][1.2.840.113549.1.1.8, [2.16.840.1.101.3.4.2.1]]]

这些错误的NULL SHA-256 值从哪里来。

【问题讨论】:

    标签: java encryption rsa bouncycastle oaep


    【解决方案1】:

    您在 BC 创建的消息中只提到了一个“额外”NULL,但实际上有两个,第一行中的第二个是您从发布的数据中排除的。您帖子中的(不同)长度字段以及getParameters() 的显示清楚地表明了这一点。

    那些 NULL 没有错。

    那些 NULL 是 OAEP 参数结构中的哈希算法的参数,并且是标准要求的。来自RFC 3447 = PKCS1v2.1,这是第一个在 A.2.1 中包含 SHA-2 的版本(2003 年,紧随 2002 年的 FIPS 186-2):

    The parameters field ... shall have a value of type RSAES-OAEP-params:
    
          RSAES-OAEP-params ::= SEQUENCE {
              hashAlgorithm     [0] HashAlgorithm    DEFAULT sha1,
              maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
              pSourceAlgorithm  [2] PSourceAlgorithm DEFAULT pSpecifiedEmpty
          }
    ...
             HashAlgorithm ::= AlgorithmIdentifier {
                {OAEP-PSSDigestAlgorithms}
             }
    
             OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
                 { OID id-sha1 PARAMETERS NULL   }|
                 { OID id-sha256 PARAMETERS NULL }|
                 { OID id-sha384 PARAMETERS NULL }|
                 { OID id-sha512 PARAMETERS NULL },
                 ...  -- Allows for future expansion --
             }
    ...
             MaskGenAlgorithm ::= AlgorithmIdentifier {
                {PKCS1MGFAlgorithms}
             }
             PKCS1MGFAlgorithms    ALGORITHM-IDENTIFIER ::= {
                 { OID id-mgf1 PARAMETERS HashAlgorithm },
                 ...  -- Allows for future expansion --
             }
    

    请注意,哈希规范(标签的外部哈希和 MGF1 参数中的内部哈希)均由 infoset HashAlgorithm 定义,并且该集中所有定义的值(包括 SHA-256)的参数显式为 NULL , 因为通用 X.509 ASN.1 允许,所以不会省略(比较 RFC5280 4.1.1.2,它使用较旧的 pre-infoset 表示法)。

    请注意,A.2.3 中的 PSS 也是如此,A.2.4 中的 RSASSA-PKCS1-v1_5 中的 DigestInfo 的散列算法集稍大一些。这和 v2.0 中的等效规定(不包括不在 2.0 中的 PSS,并且符号略有不同)可能是对 10.1.2 中的PKCS1v1.5 的反应,仅将签名 DigestInfo 参数设为“应该”(甚至小写2119 年之后大概是因为这是 RSALabs 文本而不是 IETF),这导致了实现的变化,导致实际上正确的签名有时无法验证,这被认为是一件需要修复的坏事。

    因此,您的“参考”文件在技术上违反了标准。然而,由于这些散列算法实际上并不使用参数——这就是它们使用 NULL 编码的原因——BouncyCastle 可以很容易地容忍并接受省略的情况。我用一个有效的结构进行了测试,它确实可以双向工作。 (如果它甚至可以使用一些不适当的值,例如插入其中的八位字节字符串,我也不会感到惊讶,但我没有对此进行测试。)

    即使参数编码错误,它也不会导致您遇到的异常 - 它可能是显式解码/解析错误,例如“缺少必填字段”或实例化错误,例如“算法参数无效” X'。在没有错误的情况下,“错误填充”是由损坏、篡改或其他错误数据(在 CMS 环境中不太可能发生)或不匹配的键引起的。

    检查您是否使用了匹配的密钥。

    【讨论】:

    • 感谢您的详细解答。进一步调试后,发现联合多个接收者解密时出错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-22
    • 2017-05-24
    • 1970-01-01
    • 2016-10-14
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    相关资源
    最近更新 更多