为什么在Python加密RSA加密的AES密钥解密中引发错误?

时间:2018-07-23 22:48:15

标签: encryption rsa aes asn.1

我正在尝试从已以RSA格式加密的DER编码文件中解密AES密钥。使用以下代码:

         for key, value in configfile['File Extensions'].items():
            if filename.endswith(value):
                pemFile=r'C:\Users\Public\Music\Sample Music\pkcs7.pem'
                with open(pemFile,'r') as f:
                    pem = f.read()
                # remove the -----BEGIN PKCS7----- header/footer
                    pemsplit=pem.split('\\n')
                    j =''.join(pemsplit[1:-2])
                    env_der = base64.b64decode(j)
                #print(env_der)
                    f.closed

      # merge files and then compare
                    content, rest = decode(env_der, asn1Spec=rfc2315.ContentInfo())
                    assert content['contentType'] == rfc2315.envelopedData

                    myenvelop, rest = decode(content['content'], asn1Spec=rfc2315.EnvelopedData())

                    lenencryptedkey=len(myenvelop['recipientInfos'][0]['encryptedKey'])
                    #print(lenencryptedkey)
                    encryptedsessionkey=myenvelop['recipientInfos'][0]['encryptedKey']
                    from cryptography.hazmat.primitives.asymmetric import padding
                    try:

            #this next line is a command to decrypt the encrypted AES session key with the private key.
                    decryptedsessionkey=private_key.decrypt(bytes(encryptedsessionkey), padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),algorithm=hashes.SHA256(), label=None))

我得到这个结果:

Traceback (most recent call last):
  File "C:/Users/VoxaiLap10/Desktop/pythonbible/cryptotest7-23-18_testpart1.py", line 111, in <module>
    decryptedsessionkey=private_key.decrypt(bytes(encryptedsessionkey), padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),algorithm=hashes.SHA256(), label=None))
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\cryptography\hazmat\backends\openssl\rsa.py", line 362, in decrypt
    return _enc_dec_rsa(self._backend, self, ciphertext, padding)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\cryptography\hazmat\backends\openssl\rsa.py", line 68, in _enc_dec_rsa
    return _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\cryptography\hazmat\backends\openssl\rsa.py", line 130, in _enc_dec_rsa_pkey_ctx
    _handle_rsa_enc_dec_error(backend, key)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\cryptography\hazmat\backends\openssl\rsa.py", line 161, in _handle_rsa_enc_dec_error
    raise ValueError("Decryption failed.")
ValueError: Decryption failed.

该错误似乎发生在python crypt模块中,但是我无法弄清楚到底是什么错误。我考虑过私钥不是用于加密会话密钥的公钥的正确值的可能性;您是否认为这是导致错误的原因? 这是错误即将发生的相关RSA.py库文件。

    outlen = backend._ffi.new("size_t *", buf_size)
    buf = backend._ffi.new("unsigned char[]", buf_size)
    res = crypt(pkey_ctx, buf, outlen, data, len(data))
    print(buf)
    print(outlen)
    print(data)
    print(len(data))
    print(res)
    if res <= 0:
        _handle_rsa_enc_dec_error(backend, key)

    return backend._ffi.buffer(buf)[:outlen[0]]


def _handle_rsa_enc_dec_error(backend, key):
    errors = backend._consume_errors()
    assert errors
    assert errors[0].lib == backend._lib.ERR_LIB_RSA
    if isinstance(key, _RSAPublicKey):
        assert (errors[0].reason ==
                backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE)
        raise ValueError(
            "Data too long for key size. Encrypt less data or use a "
            "larger key size."
        )
    else:
        decoding_errors = [
            backend._lib.RSA_R_BLOCK_TYPE_IS_NOT_01,
            backend._lib.RSA_R_BLOCK_TYPE_IS_NOT_02,
            backend._lib.RSA_R_OAEP_DECODING_ERROR,
            # Though this error looks similar to the
            # RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE, this occurs on decrypts,
            # rather than on encrypts
            backend._lib.RSA_R_DATA_TOO_LARGE_FOR_MODULUS,
        ]
        if backend._lib.Cryptography_HAS_RSA_R_PKCS_DECODING_ERROR:
            decoding_errors.append(backend._lib.RSA_R_PKCS_DECODING_ERROR)

        assert errors[0].reason in decoding_errors
        print(errors[0].reason)
        raise ValueError("Decryption failed.") 

调用res函数得到的crypt值为-1;你知道这代表什么吗?

1 个答案:

答案 0 :(得分:3)

  

调用crypt函数的res值为-1;你知道这代表什么吗?

如果python在下面调用OpenSSL,并且错误代码与OpenSSL完全匹配,则强烈建议使用it means any error other than unsupported。要获取详细信息,您需要查看OpenSSL的“错误队列”,大概errors = backend._consume_errors()就是这样做的。尽管您可以获得的大多数详细信息仍然无法告诉您问题的原因。

  

我考虑了私钥不是用于加密会话密钥的公钥的正确值的可能性;您是否认为这是导致错误的原因?

当然可以;用错误的密钥(但大小正确)进行RSA解密 会给出超出模数的错误,或者以压倒性的可能性产生有效的随机垃圾数据,从而导致填充错误。您可以尝试查看RecipientInfo.issuerAndSerialNumber(在CMS rfc2630 +中重命名为rid),以确保它是或至少看起来像您密钥的(或)正确标识符。如果有多个收件人,则您可能不是[0]

这也可能是错误的方案;您应该检查RecipientInfo.keyEncryptionAlgorithm。它也可能是错误的(已修改或篡改的)加密数据,但是PEM格式的消息不太可能被意外破坏但仍会解析,因此,这要么是攻击,要么是发件人中的错误。

由于该文件位于文件中,您可以使用命令行openssl smime -inform pem -decrypt进行检查吗?