我正在尝试从已以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;你知道这代表什么吗?
答案 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
进行检查吗?