问题
I'm developing a website using this JS plugin to encrypt some data and send it to the server: https://github.com/travist/jsencrypt
I'm running Python 3 with Django, the problem is I can't decrypt the data on the server. My code is:
JS Code:
pkey = "-----BEGIN PUBLIC KEY-----\
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDeVs9mcWUtTgi93/KXMNA/IF7S\
oQcZAmKQueygoDp9XUM3xnxPb/6XNpJQII85Hxbljqs/xuPVtxo5ovyJ+XXIPV8+\
eG6kSDmr2C3NpBUtfoUeADC/1H1jy44T6stBgXGMwTPokhjvSyEbGpkgMGo74Rpq\
q1vHofh3KcPNoaYH4wIDAQAB\
-----END PUBLIC KEY-----";
var encrypter = new JSEncrypt;
encrypter.setPublicKey(pkey);
encrypter.encrypt('Testing...');
And I get:
"STg7Fnm6Y6cAgMXEt4SxP8rbMb/pFB2X9Y1z8pAOoCNO9y8XuhVmQuG/FRBSqM+3ge43x9kfYMideAUu69RothwEOYmNnVrfwqm7SLm3voEcSXCqst2S7prTmCvYW43WyAAUl0vNxV+7xsm/yciQ4XV+jZSKd3xidbWL1BTTUw8="
Python Code:
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from base64 import *
def decrypt(key, text):
if type(key) == str:
key = key.encode()
if type(text) == str:
text = text.encode()
rsakey = RSA.importKey(key)
rsakey = PKCS1_OAEP.new(rsakey)
d = rsakey.decrypt(text)
return d
text = "STg7Fnm6Y6cAgMXEt4SxP8rbMb/pFB2X9Y1z8pAOoCNO9y8XuhVmQuG/FRBSqM+3ge43x9kfYMideAUu69RothwEOYmNnVrfwqm7SLm3voEcSXCqst2S7prTmCvYW43WyAAUl0vNxV+7xsm/yciQ4XV+jZSKd3xidbWL1BTTUw8="
text = b64decode(text.encode())
with open('private.pem', 'rb') as f:
key = f.read()
decrypt(key, text)
And I get:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.2/dist-packages/Crypto/Cipher/PKCS1_OAEP.py", line 227, in decrypt
raise ValueError("Incorrect decryption.")
ValueError: Incorrect decryption.
The private key I'm using in this example is:
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCO9YbJ8Z+tW0ucnMdXGNzmcvWaaLRGsx5iUHslbZ1tjec63HDm
6Hr2hv56u5zytyF4Cd/0lBNRC9qf/1XlEFqeSRifsyHZpPfyZn0fbHWYLH8g5FE4
VqrMe79ubSVx2eGWwwaLvEO+yaO1AF/fxWT6Ir8AUikMFFAnX+fBaA3XIwIDAQAB
AoGADxuniQP+CgYR8ZUoA+5eugQALLdQBgC7/0veF9CDyKYsf634SI7dH9yYXEQj
jAsKgHMatfBIMlJ8YlhLrY+S4+r26goNEqygtqetJ6NuePKQQ8xEERP4icsaBpY7
WqeU6AZOMlyq8o+e4DMnuxGpf8UT+lLx1G9AmVJf3+6NONECQQDLX94BmW//48Y6
yg9wnO6TR1msrGd1PFRqyJ9eilj8chI2JxiHkhepiTlBU7eyjUv4aeE7U84mp3Zo
AtPoiKmlAkEAs/OQM9IDttfgdS/yK6vZr1myNAbKOdv1rVId7MAspGHbN//gzb4s
r4mZKsIAi+jaDhpMvYbUxJe9y5HAY3XTJwJAe3hcZEQvRv+WHaMG9KuR/EBZJQgW
V4qlBZ9/gfokRD9M5yudLNF5JCh3Zj3ZTMGT2eEOKOKcScNpk4QD+yzdMQJAQlSM
Gd3WyqXmMav7qwdMVStN2YmLLyqZ80oqh6MKkYkUgh7KYWwxEn84ux8JjojFH5+o
G9BASzrXldrivIaozwJAVAHr9ON/altcDyh/OjkJff/3xXzHB3Zxvy4WykkO/PdF
tOqpAnYso3mCsEQsCcrJCflkFmJuYsvu4+Tm4GiqVg==
-----END RSA PRIVATE KEY-----
If I try to decrypt it on JS it works as intended:
private = "-----BEGIN RSA PRIVATE KEY-----\
MIICWwIBAAKBgQCO9YbJ8Z+tW0ucnMdXGNzmcvWaaLRGsx5iUHslbZ1tjec63HDm\
6Hr2hv56u5zytyF4Cd/0lBNRC9qf/1XlEFqeSRifsyHZpPfyZn0fbHWYLH8g5FE4\
VqrMe79ubSVx2eGWwwaLvEO+yaO1AF/fxWT6Ir8AUikMFFAnX+fBaA3XIwIDAQAB\
AoGADxuniQP+CgYR8ZUoA+5eugQALLdQBgC7/0veF9CDyKYsf634SI7dH9yYXEQj\
jAsKgHMatfBIMlJ8YlhLrY+S4+r26goNEqygtqetJ6NuePKQQ8xEERP4icsaBpY7\
WqeU6AZOMlyq8o+e4DMnuxGpf8UT+lLx1G9AmVJf3+6NONECQQDLX94BmW//48Y6\
yg9wnO6TR1msrGd1PFRqyJ9eilj8chI2JxiHkhepiTlBU7eyjUv4aeE7U84mp3Zo\
AtPoiKmlAkEAs/OQM9IDttfgdS/yK6vZr1myNAbKOdv1rVId7MAspGHbN//gzb4s\
r4mZKsIAi+jaDhpMvYbUxJe9y5HAY3XTJwJAe3hcZEQvRv+WHaMG9KuR/EBZJQgW\
V4qlBZ9/gfokRD9M5yudLNF5JCh3Zj3ZTMGT2eEOKOKcScNpk4QD+yzdMQJAQlSM\
Gd3WyqXmMav7qwdMVStN2YmLLyqZ80oqh6MKkYkUgh7KYWwxEn84ux8JjojFH5+o\
G9BASzrXldrivIaozwJAVAHr9ON/altcDyh/OjkJff/3xXzHB3Zxvy4WykkO/PdF\
tOqpAnYso3mCsEQsCcrJCflkFmJuYsvu4+Tm4GiqVg==\
-----END RSA PRIVATE KEY-----\
"
text = "STg7Fnm6Y6cAgMXEt4SxP8rbMb/pFB2X9Y1z8pAOoCNO9y8XuhVmQuG/FRBSqM+3ge43x9kfYMideAUu69RothwEOYmNnVrfwqm7SLm3voEcSXCqst2S7prTmCvYW43WyAAUl0vNxV+7xsm/yciQ4XV+jZSKd3xidbWL1BTTUw8="
encrypter.setPrivateKey(private);
encrypter.decrypt(text);
And I get:
"Testing"
But I just can't make it work on Python.
What am I doing wrong?
回答1:
jsencrypt depends on the jsbn library which doesn't provide OAEP, but only PKCS#1 v1.5 padding.
You have to use the same in python which PyCrypto provides. Simply use PKCS1_v1_5
instead of PKCS1_OAEP
.
Note that PKCS#1 v1.5 padding shouldn't be used today anymore. I suggest you use the forge library which provides an RSA implementation with OAEP.
回答2:
Using PKCS1_v1_5:
def decrypt(key, text):
if type(key) == str:
key = key.encode()
if type(text) == str:
text = text.encode()
rsakey = RSA.importKey(key)
rsakey = PKCS1_v1_5.new(rsakey)
d = rsakey.decrypt(text, 'bollox')
return d
>>> decrypt(text, key)
b'Testing'
回答3:
I had been using JSEncrypt JavaScript file to achieve conversation between JavaScript and Python using pycrypto however during encryption in JavaScript it uses a random pad in the function pkcs1pad2 which needed to be removed and it started working. It had been a hack but it worked out. Following are the lines are commented out from function pkcs1pad2(s,n)
while(n > 2) { // random non-zero pad
x[0] = 0;
while(x[0] == 0) rng.nextBytes(x);
ba[--n] = x[0];
}
ba[--n] = 2;
ba[--n] = 0;
来源:https://stackoverflow.com/questions/29581319/use-rsa-to-encrypt-in-javascript-and-decrypt-in-python3