Передача зашифрованных данных между Python Gae и клиентом

Я пытаюсь научиться передавать зашифрованные данные между сервером (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)


person Horacio Molino    schedule 27.07.2015    source источник
comment
Спасибо, Артём. Приступим к изучению JSBN.   -  person Horacio Molino    schedule 27.07.2015


Ответы (1)


1. Отправка открытого ключа клиенту

Клиенту нужен только открытый ключ, чтобы зашифровать что-то, что сервер может затем расшифровать. Открытый ключ RSA состоит из модуля n и открытого показателя степени e. Простым способом было бы отправить обе части в виде строк в шестнадцатеричном кодировании.

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

2. Использование открытого ключа для шифрования

CryptoJS не предоставляет реализацию RSA, но jsbn (GitHub). Хорошо, что мы отправили общедоступные компоненты в шестнадцатеричном формате, потому что jsbn ожидает, что модуль и общедоступная экспонента будут строками в шестнадцатеричном коде:

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

Имейте в виду, что RSA может шифровать только данные, которые не больше модуля. Если вы сгенерируете 1024-битные ключи, вы не сможете зашифровать данные размером более 1024 бит. Если вы хотите зашифровать большие данные, вам понадобится гибридное шифрование, например, с AES.

jsbn также использует только дополнение PKCS#1 v1.5, которое поддерживает pycrypto. Вы можете попробовать еще не объединенный pull request #3, чтобы получить PKCS#1 v2 OAEP. что более безопасно, чем дополнение v1.5.

3. Расшифровка на питоне

jsbn возвращает зашифрованный текст в шестнадцатеричном формате. Вы можете смело отправлять его как хотите, но вам нужно декодировать (не показано) его в байты перед расшифровкой в ​​​​питоне.

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")
person Artjom B.    schedule 27.07.2015
comment
Предложенный план очень помог мне в моем исследовании. Я также нашел завершенный пример с использованием AES, в котором полностью изложены нужные мне протоколы: Шифрование: от PyCrypto до CryptoJS по адресу gist.github.com/marcoslin/8026990 - person Horacio Molino; 05.08.2015
comment
@Горацио Это хорошо. Если вы видите проблему в моем коде, вы можете предложить правку (добавить четкое изложение правки, иначе она будет отклонена рецензентами) или сообщить мне об этом в комментарии. Вы также можете добавить свой собственный ответ, если у вас есть полное и аннотированное решение. - person Artjom B.; 05.08.2015
comment
Прежде чем я добавлю свой собственный ответ: зашифрованная клиентом строка (почти) правильно расшифрована на сервере, за исключением того, что расшифрованная строка представляет собой набор начальных непечатных символов. Что я делаю неправильно? github.com/HoracioMolino/pythonGaeAES - person Horacio Molino; 06.08.2015
comment
Я не смотрел код, но думаю, что вы используете неправильное дополнение. Если вы печатаете полученный открытый текст в шестнадцатеричном формате, видите ли вы 0x0002 байта в начале? - person Artjom B.; 06.08.2015
comment
Полученный открытый текст в шестнадцатеричном виде: 02:62:3a:2d:d5:57:d3:de:d1:9b:ba:b5:2a:70:63:72:d8:a0:45:7c:81:65: 33:77:24:d6:24:e3:4f:ec:c4:be:e7:24:18:37:dc:46:8b:0b:28:7e:f9:a7:bc:e9:51: 12:dd:cb:59:e4:65:b9:15:15:da:64:be:01:a8:25:28:b1:d0:a7:0a:1f:79:86:95:c8: 3d:d6:e2:c3:4d:b0:cf:97:23:6b:2f:b5:3d:58:00:54:68:69:73:20:69:73:20:61:20: 70:6c:61:69:6e:20:6d:65:73:73:61:67:65:20:66:72:6f:6d:20:74:68:65:20:63:6c: 69:65:6е:74:2е - person Horacio Molino; 06.08.2015
comment
Класс RSA в python реализует только учебник RSA. Если RSA необходимо использовать в реальном мире, вам нужно использовать RSA со схемой заполнения. Класс PKCS1_v1_5, как показано в моем ответе, сочетает в себе RSA со схемой заполнения. - person Artjom B.; 07.08.2015
comment
Спасибо тебе за пояснение. Сейчас я изучу предложенную вами схему заполнения. - person Horacio Molino; 10.08.2015