Некоторая справочная информация, вы можете пропустить эту часть для фактического вопроса
это мой третий вопрос по этой теме здесь, в stackoverflow. Чтобы быть полным, это другие вопросы AES с crypt-js и PyCrypto. и Сопоставьте де/шифрование AES в python и javascript а>. К сожалению, моя последняя попытка получила два отрицательных ответа на исходный вопрос. Проблема была в том, что даже я не знал, в чем был мой настоящий вопрос. Я просто копался, чтобы найти реальный вопрос, который я искал. Получив отзывы в комментариях и прочитав дополнительную информацию, я обновил свой вопрос. Я раскапываю правильный вопрос, я думаю. Но моя проблема больше не набирала просмотров после моих обновлений. Так что я очень надеюсь, что этот вопрос теперь стал более ясным и понятным - даже я теперь знаю, в чем моя проблема :D
Спасибо всем за то, что сделали stackoverflow этому классному сообществу - я часто находил здесь решения своих проблем. Пожалуйста, продолжайте оставлять отзывы на плохие вопросы, чтобы их можно было улучшить и обновить, что увеличивает эту огромную базу знаний и решений. И не стесняйтесь исправлять мою английскую грамматику и орфографию.
Проблема
AES в Javascript
У меня есть зашифрованная строка, которую я могу расшифровать с помощью этой Javascript-реализации AES 256 CTR. Режим
password = "myPassphrase"
ciphertext = "bQJdJ1F2Y0+uILADqEv+/SCDV1jAb7jwUBWk"
origtext = Aes.Ctr.decrypt(ciphertext, password, 256);
alert(origtext)
Это расшифровывает мою строку, и появляется окно предупреждения с This is a test Text
.
AES с PyCrypto
Теперь я хочу расшифровать эту строку с помощью python и PyCrypto.
password = 'myPassphrase'
ciphertext = "bQJdJ1F2Y0+uILADqEv+/SCDV1jAb7jwUBWk"
ctr = Counter.new(nbits=128)
encryptor = AES.new(key, AES.MODE_CTR, counter=ctr)
origtext = encryptor.decrypt(base64.b64decode(ciphertext))
print origtext
Этот код не запускается. Я получаю ValueError: AES key must be either 16, 24, or 32 bytes long
. Когда я понял, что мне нужно сделать в PyCrypto больше, чем просто вызвать метод расшифровки, я начал исследовать и пытаться выяснить, что я должен делать.
Расследование
Основные вещи, которые я понял в первую очередь, были:
- AES 256 бит (?). Но стандарт AES 128 бит. Достаточно ли увеличить парольную фразу до 32 байт?
- Режим счетчика. Легко установить в PyCrypto с помощью AES.MODE_CTR. Но я должен указать метод counter(). Поэтому я использовал базовый двоичный счетчик, предоставленный PyCrypto. а>. Совместимо ли это с реализацией Javascript? Я не могу понять, что они делают.
- Строка закодирована в base64. Не большая проблема.
- Прокладка в целом. И парольная фраза, и зашифрованная строка.
Для парольной фразы они делают это:
for (var i=0; i<nBytes; i++) {
pwBytes[i] = isNaN(password.charCodeAt(i)) ? 0 : password.charCodeAt(i);
}
Затем я сделал это в питоне
l = 32
key = key + (chr(0)*(l-len(key)%l))
Но это не помогло. Я все еще получаю странную строку ?
A???B??d9= ,?h????'
со следующим кодом
l = 32
key = 'myPassphrase'
key = key + (chr(0)*(l-len(key)%l))
ciphertext = "bQJdJ1F2Y0+uILADqEv+/SCDV1jAb7jwUBWk"
ctr = Counter.new(nbits=128)
encryptor = AES.new(key, AES.MODE_CTR, counter=ctr)
origtext = encryptor.decrypt(base64.b64decode(ciphertext))
print origtext
Затем я прочитал больше о реализации Javascript, и там говорится
[...] В этой реализации начальный блок содержит одноразовый номер в первых 8 байтах и количество блоков во вторых 8 байтах. [...]
Я думаю, что это может быть ключом к решению. Итак, я проверил, что происходит, когда я шифрую пустую строку в Javascript:
origtext = ""
var ciphertext =Aes.Ctr.encrypt(origtext, password, 256);
alert(ciphertext)
В окне предупреждения отображается /gEKb+N3Y08=
(12 символов). Но почему 12? Разве это не должно быть 8+8 = 16 байт? В любом случае, я попробовал метод bruteforce для расшифровки Python, проверив расшифровку с помощью for i in xrange(0,20):
и ciphertext[i:]
или base64.b64decode(ciphertext)[i:]
. Я знаю, что это очень неловкая попытка, но я становился все более и более отчаянным. И это тоже не сработало.
Будущие перспективы также заключаются в том, чтобы реализовать шифрование таким же образом.
Дополнительная информация
Зашифрованная строка изначально не была зашифрована с помощью этой реализации Javascript. другой источник. Я только что понял, что код Javascript работает правильно. Поэтому я утверждаю, что такая реализация является чем-то вроде "стандарта".
Вопрос
Что я могу сделать, чтобы шифрование и дешифрование строки с PyCrypto было таким же, как в реализации Javascript, чтобы я мог обмениваться данными между Javascript и Python? Я бы также переключился на другую криптобиблиотеку на питоне, если вы можете предложить другую. Кроме того, я рад любым советам и отзывам.
И я думаю, что все сводится к Как я могу включить одноразовый номер и количество блоков в зашифрованную строку? и Как я могу извлечь эту информацию для расшифровки?