2012-04-11 3 views
2

Я пытаюсь использовать PyCrypto для шифрования/дешифрования некоторых строк, и у меня возникают проблемы с китайскими иероглифами.PyCrypto: кодирование китайских символов с асимметричным ключом RSA

При попытке зашифровать "Ni-хао" (привет) ...

pemFile = open("/home/borrajax/keys/myKey.pem", "r") 
encryptor = RSA.importKey(pemFile, passphrase="f00") 
return encryptor.encrypt("你好", 0)[0] 

... Я продолжаю получать ошибки:

Module Crypto.PublicKey.pubkey:64 in encrypt   
>> ciphertext=self._encrypt(plaintext, K) 
Module Crypto.PublicKey.RSA:92 in _encrypt   
>> return (self.key._encrypt(c),) 
ValueError: Plaintext too large 

Я перепробовал много комбинации,

encryptor.encrypt(u"你好"... 
encryptor.encrypt(u"你好".encode("utf-8")... 

не имеет при удаче.

Я предполагаю, что всегда мог бы использовать base64 перед кодированием, но я хотел бы оставить это как «последний ресурс» ... Я надеялся на более «элегантный» способ сделать это.

С кем-либо сталкивались те же проблемы? Любой намек будет оценен. Заранее спасибо.

ответ

2

Во-первых, вы должны шифровать только двоичные данные, а не Unicode текст. Это означает, что тип str (в Python 2.x) или bytes (в Python 3.x и последний Python 2.x). Вы должны кодировать текст перед его шифрованием, и вы должны декодировать его после дешифрования.

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

В-третьих, если вы используете PyCrypto 2.5, нет веских оснований для использования методов .encrypt/.decrypt ключевого объекта RSA. Лучше и безопаснее использовать один из методов PKCS # 1: OAEP или v1.5. С ними открытый текст должен быть еще короче.

1

Я тестировал с PyCrypto v2.5, установленный из pip на Ubuntu Linux 10.04 на python 2.6.5 в интерактивном интерпретаторе с терминала yakuake.

Я не могу воспроизвести ошибку, которую вы видите, особенно бит «Plaintext too large». Некоторые ошибки, которые я видел:

encryptor.encrypt(u"你好",0)[0] 

TypeError: argument 1 must be long, not unicode 

Похоже, что он не любит объекты юникода - только хочет str.

Обе эти работы на моей установке, и оба производят тот же результат, однако первое решение является более правильным:

encryptor.encrypt(u"你好".encode("utf-8"), 0)[0] 
encryptor.encrypt("你好", 0)[0] 

Вы пытаетесь это от интерактивного интерпретатора, или из файла? Если файл, i s the file UTF-8 encoded? Если консоль, имеет ли она надлежащую поддержку UTF-8?

1

Я проверил связанные коды PyCrypto, эта ошибка возникает только в том случае, если текстовый текст (после преобразования в длинный) больше одного из ключевых параметров. Предполагая, что кодировка сценария установлена ​​правильно, это может быть связано с тем, что ваш ключ RSA недействителен или слишком короткий. Я попробовал этот фрагмент кода, он работает без проблем:

rsa = RSA.generate(1024) 

print(rsa.encrypt("你好", 0))