我正在尝试学习如何在服务器(Python gae)和客户端(jquery)之间传递加密数据
服务器上的代码片段的以下草图可以工作:
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)
我不明白将客户端可以用来加密的公钥传递给客户端的内容 (使用http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js)
答案 0 :(得分:1)
客户端只需要公钥来加密服务器然后可以解密的内容。 RSA公钥由模数 n 和公共指数 e 组成。简单的方法是将两个部分作为十六进制编码的字符串发送。
modulus = hex(key.publickey().n)[2:-1]
exponent = hex(key.publickey().e)[2:-1]
CryptoJS没有提供RSA实现,但jsbn(GitHub)确实如此。我们将公共组件作为十六进制发送是件好事,因为jsbn期望模数和公共指数为十六进制编码字符串:
var rsa = new RSA();
rsa.setPublic(n_string, e_string);
var res = rsa.encrypt(plaintext);
请记住,RSA只能加密模数不大的数据。如果生成1024位密钥,则无法加密大于1024位的数据。如果您想加密更大的数据,则需要Hybrid Encryption,例如AES。
jsbn也只使用pycrypto支持的PKCS#1 v1.5填充。您可以尝试使用尚未合并的pull request #3来获取比v1.5填充更安全的PKCS#1 v2 OAEP。
jsbn返回十六进制编码的密文。您可以根据需要安全地发送它,但是您需要在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")