简体   繁体   中英

Passing encrypted data between Python Gae and Client

I am trying to learn how to pass encrypted data between server (Python gae) and client(jquery)

The following sketch of a code fragment at the server works:

random_generator = Random.new().read
key = RSA.generate(1024,random_generator)

publicKey        =  key.publickey()
clearText        =  "this is a test message"
b64Text          =  base64.b64encode(clearText)
ecryptedText     =  publicKey.encrypt(b64Text,32)

b64DecryptedText =  key.decrypt(encryptedText)  
clearText        =  base64.b64decode(b64DecryptedText)

I do not understand what to pass to the client as a public key which the client can use to encrypt (using http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js )

1. Sending public key to the client

The client only needs the public key to encrypt something that the server can then decrypt. An RSA public key is made up of the modulus n and the public exponent e . The easy way would be to send both parts as hex-encoded strings.

modulus = hex(key.publickey().n)[2:-1]
exponent = hex(key.publickey().e)[2:-1]

2. Using public key to encrypt

CryptoJS doesn't provide an RSA implementation, but jsbn ( GitHub ) does. It's a good thing that we sent the public components as hex, because jsbn expects the modulus and public exponent as hex-encoded strings:

var rsa = new RSA();
rsa.setPublic(n_string, e_string);
var res = rsa.encrypt(plaintext);

Keep in mind that RSA can only encrypt data that is not bigger as the modulus. If you generate 1024-bit keys, then you can't encrypt data bigger than 1024-bit. If you want to encrypt bigger data, you need Hybrid Encryption with for example AES.

jsbn also only uses PKCS#1 v1.5 padding which pycrypto supports. You can try the non-yet merged pull request #3 to get PKCS#1 v2 OAEP which is more secure than v1.5 padding.

3. Decryption in python

jsbn returns a hex-encoded ciphertext. You can safely send it as you wish, but you need to decode (not shown) it to bytes before decryption in python.

sentinel = Random.new().read(32) # denotes the error result of the decryption 
cipher = PKCS1_v1_5.new(key) # private key
message = cipher.decrypt(ciphertext, sentinel)
if sentinel != message:
    print("success: " + str(message))
else:
    print("failure")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM