Подсказка: подумайте, как работает режим счетчика. Каково начальное значение счетчика в вашем коде и каковы последующие значения? Какими они должны быть?
counter=lambda: nonce
Это постоянная функция, которая всегда возвращает одно и то же значение, равное 0 в вашей программе. Но это не то, что вам нужно передать counter
: вам нужно передать функцию, которая возвращает текущее значение счетчика каждый раз, когда он вызывается. Например, если начальное значение счетчика равно 0, то эта функция должна возвращать 0 при первом вызове, 1 во второй раз, 2 в третий раз и т. Д. Точнее, она должна возвращать '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
, затем '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
, и т.д.
Интерфейс Python здесь плохо спроектирован. Он слишком гибкий, но на практике он никогда не бывает полезным и затрудняет правильное использование API. Кроме того, документация не совсем ясна:
counter
(вызываемый) - (Только MODE_CTR
). Функция с состоянием, которая возвращает следующий блок счетчика, который является байтовой строкой block_size
байтов. Для повышения производительности используйте Crypto.Util.Counter
.
На самом деле вам достаточно нужно , чтобы использовать Crypto.Util.Counter
не только для «производительности», но и для правильности вычислений. Не расстраивайтесь: вы не первый, кто пережил это.
Столкнувшись с API, который вы не можете понять, вы можете обратиться к Stack Overflow дальше… и на этот самый вопрос уже дан ответ, в Проблема PyCrypto с использованием AES + CTR , но остерегайтесь этого для 7 В течение многих лет этот вопрос не имел правильного ответа, несмотря на то, что он был одобрен и принят. Мой ответ показывает, как использовать MODE_CTR
и counter
.
Второй проблемой может быть начальное значение счетчика. Существует две основные стратегии выбора начального значения счетчика для режима CTR:
- Для одноразового ключа начните с 0 и не передавайте ICV с сообщением, поскольку это общеизвестная константа.
- Для ключа многократного использования генерируйте случайное значение каждый раз и отправляйте ICV в начале зашифрованного текста.
Я не знаком с API в коде шифрования, который вы разместили. Но так как он возвращает зашифрованный текст той же длины, что и открытый текст, он, вероятно, использует постоянный ICV (что хорошо для одноразового ключа, но катастрофически, если ключ используется повторно), скорее всего 0. Тем не менее, проверьте документацию этого API.
(Если вам нужна дополнительная помощь в кодировании, спросите Переполнение стека , а не Криптография , потому что вопросы кодирования не по теме в Cryptography.SE. И обязательно напишите полный код для воспроизведения проблемы , включая входы и выходы.)