Reputation: 245
I am encrypting (RSA) user input client side using JavaScript (jsencrypt), when I process it server side, I get the correct message, but there are some invalid characters that show up.
For input "Hello", I get:
\�<�>Ddž䥋��wp+6'���W=��$�O�rܨosf�.C��qKT=_�{�B��pE#�-mn��t����Y^0���L�9f@�=O*��\���B��z�;��"�0��k&��z,��J�\�LHello
The code is as follows:
<script type="text/javascript">
// Call this code when the page is done loading.
$(function() {
// Run a quick encryption/decryption when they click.
$('#testme').click(function(event) {
// Encrypt with the public key...
var encrypt = new JSEncrypt();
encrypt.setPublicKey($('#pubkey').val());
var encrypted = encrypt.encrypt($('#message').val());
$("#message").val(encrypted);
//event.preventDefault();
//alert(encrypted)
});
});
</script>
<form action="/encrypt" method="POST">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
<input type="text" placeholder="Name" name="message" id="message"/><br/>
<button id="testme">Create Order</button>
</form>
<textarea id="pubkey" hidden rows="15" cols="65">-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbbUFcBLb2dAWeZcM8YmYqA2sG nchR0N9yDFJd95FrBEwqHqxeCyJarx8O98Sn/7Cy3IE7W5wkvlFKkn1zmFkm/lK8 VYRGqg2ZvdnJ6HLcIwzqEOS9at/4gdSE/7DdXvq9iYGx1pcPoEeXgt3WlVNpxCja lbrINAS1W6+wnmDf/wIDAQAB-----END PUBLIC KEY-----</textarea>
The python code is:
def encrypt_message(request):
key64="MIICXQIBAAKBgQCbbUFcBLb2dAWeZcM8YmYqA2sGnchR0N9yDFJd95FrBEwqHqxe CyJarx8O98Sn/7Cy3IE7W5wkvlFKkn1zmFkm/lK8VYRGqg2ZvdnJ6HLcIwzqEOS9 at/4gdSE/7DdXvq9iYGx1pcPoEeXgt3WlVNpxCjalbrINAS1W6+wnmDf/wIDAQAB AoGBAJcgiOjcfLru3XfDIy9XzlcTs8FfMiS7oEjYyk4sJu2T5CsgYCGhWeorVVvM dx+Tc1C3L8FztkPT+l80SV9Yx3WpzE8t4rK80ZWWTqAoiGfXiAIovr+NtNAyH27I xI7HAYw8a6+G9OOHWf/EnBtUQZsHASY2EZl84NcEVd/3nkVhAkEAuLCcJqYlZgbS u4MX2VOtfEw+fn4xTG9Gq1gcSaQVQdti0smFZU78HsOfoW8RcqgINRrBTwv4igmu s4RsNfcgpQJBANdwLawnCKpi+S2MUzB2nSDIkcsvkrSbOPPpDMciXVXD9ImIanWa Pp5vIUO+w2YDGzR4wwkKsnz+Rb2BZb7jmNMCQGrm3xuH4/HQVT3wPWewBaUCxNGW 3ZYueqtHDuiZLyy1fdggiTQAqfJsrQNWNLU3CbkjSW0lsrDDtfl21uPNrXkCQQCV Kq3k8c31M7w2BmAfQTGAXn9cAR+B/6vKbkWTp76aQKiTham4rcjHqEiPAImIm4P9 q9PW8dot41zkXrDVH/9TAkA/qRRUKgrBvDDxAXgoyijqZt3xOMTySk5gEw7Z/5ej 4sM4M4aTT79ZV00rkbPMJm5w1OZbbBLaCW7ikLvA/hoh"
keyDER = b64decode(key64)
keyPub = RSA.importKey(keyDER)
encrypted =request.POST['message']
raw_cipher_data = b64decode(encrypted)
decrypted = keyPub.decrypt(raw_cipher_data)
return HttpResponse((decrypted))
Upvotes: 2
Views: 1532
Reputation: 61952
JSencrypt is based on JSBN which only supports RSA with PKCS#1 v1.5 padding. I suspect that RSA
is actually Crypto.PublicKey.RSA
from pyCrypto. This class only implements textbook RSA without any padding. Therefore, when you decrypt the message, the padding is not removed.
You need to use Crypto.Cipher.PKCS1_v1_5
for that.
from Crypto.Cipher import PKCS1_v1_5
key = PKCS1_v1_5.new(keyPub)
sentinel = {"error":True}
decrypted = key.decrypt(raw_cipher_data, sentinel)
if decrypted is sentinel:
print("failure")
else:
print("success: " + decrypted)
Upvotes: 1