我正在尝试使用JSEncrypt(javascript)进行RSA加密文本,并使用python crypto(python3.7)进行解密。在大多数时候,它都可以工作。但是有时候,python无法解密。
const encrypt = new JSEncrypt()
encrypt.setPublicKey(publicKey)
encrypt.encrypt(data)
from base64 import b64decode
from Crypto.Cipher import PKCS1_v1_5 as Cipher_PKCS1_v1_5
from Crypto.PublicKey import RSA
crypt_text = "J9I/IdsSGZqrQ5XBTlDrze5+U3otrGEGn7J7f330/tbIpdPNwu9k5gCh35HJHuRF6tXhbOD9XbHS6dGXwRdj0KNSWa43tDQMyGp/ZSewCd4wWkqIx83YzDKnYTVc9zWYbg2iYrmR03AqtWMysl8vZDUSmQn7gNdYEJGxSUzVng=="
private_key = "MIICXQIBAAKBgQClFImg7N+5ziGtjrMDwN7frootgwrLUmbE9YFBtecnjchCRjAn1wqq69XiWynEv0q3/U91N5g0nJxeMuolSM8cwdQbT3KZFwQF6vreSzDNhfEYOsFVZknILLPiJpUYm5w3Gi34UeM60iHGH9EUnmQeVwKSG0WF2nK2SCU6EyfoJwIDAQABAoGAHHk2Y/N3g2zykiUS64rQ5nQMkV0Q95D2+PH/oX3mqQPjjsrcc4K77E9RTQG8aps0IBgpJGa6chixP+44RMYSMvRIK0wqgX7s6AFIkFIIM+v+bP9pd3kKaVKTcNIjfnKJZokgAnU0QVdf0zeSNElZC+2qe1FbblsSQ6sqaFmHaMECQQC4oZO+w0q2smQh7VZbM0fSIbdZEimX/4y9KN4VYzPQZkDzQcEQX1Al2YAP8eqlzB4r7QcpRJgvUQDODhzMUtP9AkEA5ORFhPVK5slpqYP7pj2F+D2xAoL9XkgBKmhVppD/Sje/vg4yEKCTQ7fRlIzSvtwAvbDJi3ytYqXQWVdaD/Eb8wJAdYC3k8ecTCu6WHFA7Wf0hIJausA5YngMLPLObFQnTLFXErm9UlsmmgATZZJz4LLIXPJMBXKXXD20Qm9u2oa4TQJBAKxBopP6KiFfSNabDkLAoFb+znzuaZGPrNjmZjcRfh6zr+hvNHxQ7CMVbnNWO7AJT8FyD2ubK71GvnLOC2hd8sMCQQCT70B5EpFqULt7RBvCa7wwJsmwaMZLhBcfNmbry/J9SZG3FVrfYf15r0SBRug7mT2gRmH+tvt/mFafjG50VCnw"
decode_data = b64decode(crypt_text)
other_private_key = RSA.importKey(b64decode(private_key))
cipher = Cipher_PKCS1_v1_5.new(other_private_key)
decrypt_text = cipher.decrypt(decode_data, None).decode()
print(decrypt_text)
这是python无法解密的示例文本,但是js可以很好地解密它。 python引发错误:
File "/usr/local/lib/python3.7/site-packages/Crypto/Cipher/PKCS1_v1_5.py", line 165, in decrypt
raise ValueError("Ciphertext with incorrect length.")
ValueError: Ciphertext with incorrect length.
答案 0 :(得分:1)
如果密文是通过Base64解码的,则原因变得更加清楚:密文不具有模数的长度(128字节),而只有127字节,即,它不会被填充为模数的长度前导0x00
值。该密文无效(请参见RFC8017,第1步),并且Python代码中的解密失败,并显示错误消息长度不正确的密文。相反,JavaScript代码中的解密有效,即JSEncrypt#decrypt
通过隐式填充0x00
值,显然将密文调整为模数的长度。如果密文是使用JSEncrypt#encrypt
创建的,则此方法似乎无法正常工作。
详细信息:模数可以通过以下方式确定:
openssl rsa -modulus -noout -in <path to private key>
并且是(以十六进制字符串形式):
A51489A0ECDFB9CE21AD8EB303C0DEDFAE8A2D830ACB5266C4F58141B5E7278DC842463027D70AAAEBD5E25B29C4BF4AB7FD4F753798349C9C5E32EA2548CF1CC1D41B4F7299170405EAFADE4B30CD85F1183AC1556649C82CB3E22695189B9C371A2DF851E33AD221C61FD1149E641E5702921B4585DA72B648253A1327E827
长度为128个字节。 Base64解码的密文为(作为十六进制字符串):
27d23f21db12199aab4395c14e50ebcdee7e537a2dac61069fb27b7f7df4fed6c8a5d3cdc2ef64e600a1df91c91ee445ead5e16ce0fd5db1d2e9d197c11763d0a35259ae37b4340cc86a7f6527b009de305a4a88c7cdd8cc32a761355cf735986e0da262b991d3702ab56332b25f2f6435129909fb80d7581091b1494cd59e
长度为127字节。如果将密文手动填充为0x00
值的模数长度,则也可以在Python代码中将其解密:
0027d23f21db12199aab4395c14e50ebcdee7e537a2dac61069fb27b7f7df4fed6c8a5d3cdc2ef64e600a1df91c91ee445ead5e16ce0fd5db1d2e9d197c11763d0a35259ae37b4340cc86a7f6527b009de305a4a88c7cdd8cc32a761355cf735986e0da262b991d3702ab56332b25f2f6435129909fb80d7581091b1494cd59e
解密后的数据为:
Mzg4MDE1NDU4MTI1ODI0OA==NDQyODYwNjI1MjU4NTM2MA==
是两个有效的Base64编码字符串。
答案 1 :(得分:0)
感谢Topaco,它解决了。
from base64 import b64decode, b16decode
from Crypto.Cipher import PKCS1_v1_5 as Cipher_PKCS1_v1_5
from Crypto.PublicKey import RSA
crypt_text = \
"R247QGAFEeSW1wwXQuNf/cm/K/tnW5xwXLb5MuHW6/Fr8SRklM0n6Rmj07TgFwApeN72j/avXAvpoR70U92ehOJsDnnZguYN4u2bMXHDyTNmAXuJw9xPm59bSGcvgRm1X+V0Zq1FLzGEsPG6tOYEIX+wnIuH3P7QMd02XJfj0w0="
private_key = "MIICXQIBAAKBgQClFImg7N+5ziGtjrMDwN7frootgwrLUmbE9YFBtecnjchCRjAn1wqq69XiWynEv0q3/U91N5g0nJxeMuolSM8cwdQbT3KZFwQF6vreSzDNhfEYOsFVZknILLPiJpUYm5w3Gi34UeM60iHGH9EUnmQeVwKSG0WF2nK2SCU6EyfoJwIDAQABAoGAHHk2Y/N3g2zykiUS64rQ5nQMkV0Q95D2+PH/oX3mqQPjjsrcc4K77E9RTQG8aps0IBgpJGa6chixP+44RMYSMvRIK0wqgX7s6AFIkFIIM+v+bP9pd3kKaVKTcNIjfnKJZokgAnU0QVdf0zeSNElZC+2qe1FbblsSQ6sqaFmHaMECQQC4oZO+w0q2smQh7VZbM0fSIbdZEimX/4y9KN4VYzPQZkDzQcEQX1Al2YAP8eqlzB4r7QcpRJgvUQDODhzMUtP9AkEA5ORFhPVK5slpqYP7pj2F+D2xAoL9XkgBKmhVppD/Sje/vg4yEKCTQ7fRlIzSvtwAvbDJi3ytYqXQWVdaD/Eb8wJAdYC3k8ecTCu6WHFA7Wf0hIJausA5YngMLPLObFQnTLFXErm9UlsmmgATZZJz4LLIXPJMBXKXXD20Qm9u2oa4TQJBAKxBopP6KiFfSNabDkLAoFb+znzuaZGPrNjmZjcRfh6zr+hvNHxQ7CMVbnNWO7AJT8FyD2ubK71GvnLOC2hd8sMCQQCT70B5EpFqULt7RBvCa7wwJsmwaMZLhBcfNmbry/J9SZG3FVrfYf15r0SBRug7mT2gRmH+tvt/mFafjG50VCnw"
decode_data = b64decode(crypt_text)
if len(decode_data) == 127:
hex_fixed = '00' + decode_data.hex()
decode_data = b16decode(hex_fixed.upper())
other_private_key = RSA.importKey(b64decode(private_key))
cipher = Cipher_PKCS1_v1_5.new(other_private_key)
decrypt_text = cipher.decrypt(decode_data, None).decode()
print(decrypt_text)