Есть ли в Python встроенный простой способ кодирования / декодирования строк с помощью пароля?
Что-то вроде этого:
>>> encode('John Doe', password = 'mypass')
'sjkl28cn2sx0'
>>> decode('sjkl28cn2sx0', password = 'mypass')
'John Doe'
Таким образом, строка «Джон Доу» зашифровывается как sjkl28cn2sx0. Чтобы получить исходную строку, я "разблокирую" эту строку с помощью ключа mypass, который является паролем в моем исходном коде. Я бы хотел, чтобы это был способ шифрования / дешифрования документа Word с помощью пароля.
Я хотел бы использовать эти зашифрованные строки в качестве параметров URL. Моя цель - обфускация, а не усиленная безопасность; ничего критически важного не кодируется. Я понимаю, что могу использовать таблицу базы данных для хранения ключей и значений, но стараюсь быть минималистичным.
Ответы:
Предполагая , что вы только ищете простое запутывание , что будет затруднять вещи из очень стороннего наблюдателя, и вы не хотите использовать сторонние библиотеки. Я бы порекомендовал что-то вроде шифра Виженера. Это один из самых сильных древних простых шифров.
Шифр Виженера
Это быстро и легко реализовать. Что-то вроде:
Декодирование почти такое же, за исключением вычитания ключа.
Гораздо труднее сломать, если строки, которые вы кодируете, короткие и / или если трудно угадать длину используемой ключевой фразы.
Если вы ищете что-то криптографическое, PyCrypto, вероятно, ваш лучший выбор, хотя в предыдущих ответах упускаются некоторые детали: режим ECB в PyCrypto требует, чтобы ваше сообщение было кратным 16 символам в длину. Итак, вы должны набить. Также, если вы хотите использовать их как параметры URL, используйте
base64.urlsafe_b64_encode()
, а не стандартный. Это заменяет некоторые символы в алфавите base64 на URL-безопасные символы (как следует из названия).Однако вы должны быть АБСОЛЮТНО уверены, что этого очень тонкого слоя обфускации достаточно для ваших нужд, прежде чем использовать его. Статья в Википедии, на которую я ссылаюсь, содержит подробные инструкции по взлому шифра, поэтому любой, кто обладает умеренной решимостью, может легко взломать его.
источник
'str' object cannot be interpreted as an integer
Поскольку вы прямо заявляете, что вам нужна неясность, а не безопасность, мы не будем упрекать вас за слабость того, что вы предлагаете :)
Итак, используя PyCrypto:
Если кто-то завладеет вашей базой данных и вашей кодовой базой, он сможет расшифровать зашифрованные данные. Береги себя
secret_key
!источник
encrypt
функция имеет состояние dlitz.net/software/pycrypto/api/current/… поэтому вам не следует пытаться использовать ее повторно.Python не имеет встроенных схем шифрования, нет. Вы также должны серьезно относиться к хранению зашифрованных данных; тривиальные схемы шифрования, которые один разработчик считает небезопасными, а игрушечная схема вполне может быть ошибочно принята менее опытным разработчиком за безопасную схему. Если вы зашифруете, зашифруйте правильно.
Однако вам не нужно много работать, чтобы реализовать правильную схему шифрования. Прежде всего, не изобретайте заново колесо криптографии , используйте надежную библиотеку криптографии , которая сделает это за вас. Для Python 3 это надежная библиотека
cryptography
.Я также рекомендую применять шифрование и дешифрование к байтам ; сначала кодируйте текстовые сообщения в байты;
stringvalue.encode()
кодируется в UTF8, легко восстанавливается снова с помощьюbytesvalue.decode()
.И последнее, но не менее важное: при шифровании и дешифровании мы говорим о ключах , а не о паролях. Ключ не должен быть запоминающимся человеком, это то, что вы храните в секретном месте, но машиночитаемо, тогда как пароль часто можно прочитать и запомнить. Вы можете получить ключ из пароля, немного осторожно.
Но для веб-приложения или процесса, запущенного в кластере без участия человека, вы хотите использовать ключ. Пароли используются, когда доступ к определенной информации требуется только конечному пользователю. Даже в этом случае вы обычно защищаете приложение паролем, а затем обмениваетесь зашифрованной информацией с помощью ключа, возможно, привязанного к учетной записи пользователя.
Шифрование с симметричным ключом
Fernet - AES CBC + HMAC, настоятельно рекомендуется
В
cryptography
библиотеке есть рецепт Fernet , передовой рецепт использования криптографии. Fernet - это открытый стандарт с готовыми реализациями на широком спектре языков программирования, который включает в себя шифрование AES CBC с информацией о версии, меткой времени и подписью HMAC для предотвращения подделки сообщений.Fernet делает его очень легким для шифровки и дешифровки сообщений и держать вас безопасным. Это идеальный метод для шифрования данных с секретом.
Я рекомендую вам использовать
Fernet.generate_key()
для генерации безопасного ключа. Вы также можете использовать пароль (следующий раздел), но полный 32-байтовый секретный ключ (16 байтов для шифрования плюс еще 16 для подписи) будет более безопасным, чем большинство паролей, о которых вы могли подумать.Ключ, который генерирует Fernet, представляет собой
bytes
объект с URL-адресом и безопасными для файла символами base64, поэтому его можно распечатать:Чтобы зашифровать или расшифровать сообщения, создайте
Fernet()
экземпляр с заданным ключом и вызовитеFernet.encrypt()
илиFernet.decrypt()
, и текстовое сообщение для шифрования, и зашифрованный токен являютсяbytes
объектами.encrypt()
иdecrypt()
функции будут выглядеть так:Демо-версия:
Фернет с паролем - ключ, полученный из пароля, несколько снижает безопасность
Вы можете использовать пароль вместо секретного ключа при условии, что вы используете надежный метод получения ключа . Затем вам нужно включить соль и счетчик итераций HMAC в сообщение, чтобы зашифрованное значение больше не было совместимо с Fernet без предварительного разделения соли, счетчика и токена Fernet:
Демо-версия:
Включение соли в вывод позволяет использовать случайное значение соли, что, в свою очередь, гарантирует, что зашифрованный вывод гарантированно будет полностью случайным независимо от повторного использования пароля или повторения сообщения. Включение счетчика итераций гарантирует, что вы можете настроить увеличение производительности ЦП с течением времени, не теряя возможности расшифровывать старые сообщения.
Один только пароль может быть таким же безопасным, как 32-байтовый случайный ключ Fernet, при условии, что вы сгенерируете правильно случайный пароль из пула аналогичного размера. 32 байта дают вам 256 ^ 32 количество ключей, поэтому, если вы используете алфавит из 74 символов (26 верхних, 26 нижних, 10 цифр и 12 возможных символов), то ваш пароль должен быть не менее
math.ceil(math.log(256 ** 32, 74))
== 42 символа. Однако правильно подобранное большее количество итераций HMAC может несколько смягчить недостаток энтропии, поскольку это делает для злоумышленника гораздо более затратным проникновение в систему.Просто знайте, что выбор более короткого, но все же достаточно безопасного пароля не повредит эту схему, он просто уменьшит количество возможных значений, которые злоумышленник должен будет перебирать; убедитесь, что вы выбрали достаточно надежный пароль для ваших требований безопасности .
альтернативы
Сокрытие
Альтернатива - не шифрование . Не поддавайтесь соблазну просто использовать шифр с низким уровнем защиты или самодельную реализацию, скажем, Vignere. Эти подходы не обеспечивают безопасности, но могут дать неопытному разработчику, которому поручено поддерживать ваш код в будущем, иллюзию безопасности, что хуже, чем отсутствие безопасности вообще.
Если все, что вам нужно, это неясность, просто используйте base64 для данных; для требований к безопасности URL-адресов
base64.urlsafe_b64encode()
функция в порядке. Не используйте здесь пароль, просто закодируйте, и все готово. В лучшем случае добавьте немного сжатия (напримерzlib
):Это превращается
b'Hello world!'
вb'eNrzSM3JyVcozy_KSVEEAB0JBF4='
.Только честность
Если все, что вам нужно, это способ убедиться, что данные можно доверять, чтобы они не были изменены после того, как они были отправлены ненадежному клиенту и получены обратно, тогда вы хотите подписать данные, вы можете использовать
hmac
библиотеку для этого с помощью SHA1 (все еще считается безопасным для подписи HMAC ) или лучше:Используйте это для подписи данных, затем прикрепите подпись с данными и отправьте ее клиенту. Когда вы получите данные обратно, разделите данные и подпись и проверьте. Я установил алгоритм по умолчанию SHA256, поэтому вам понадобится 32-байтовый ключ:
Вы можете посмотреть
itsdangerous
библиотеку , которая объединяет все это с сериализацией и десериализацией в различных форматах.Использование шифрования AES-GCM для обеспечения шифрования и целостности
Fernet основан на AEC-CBC с подписью HMAC для обеспечения целостности зашифрованных данных; злонамеренный злоумышленник не может кормить вашу систему бессмысленными данными, чтобы ваша служба была занята кругами с неверным вводом, потому что зашифрованный текст подписан.
Галуа / Счетчик Режим блочного шифра производит зашифрованный текст и тег , чтобы служить той же цели, поэтому могут быть использованы , чтобы служить той же цели. Обратной стороной является то, что, в отличие от Fernet, не существует простого универсального рецепта, который можно было бы использовать на других платформах. AES-GCM также не использует заполнение, поэтому этот зашифрованный текст шифрования соответствует длине входного сообщения (тогда как Fernet / AES-CBC шифрует сообщения до блоков фиксированной длины, несколько скрывая длину сообщения).
AES256-GCM принимает в качестве ключа обычный 32-байтовый секрет:
затем используйте
Я включил временную метку для поддержки тех же сценариев использования, что и Fernet.
Другие подходы на этой странице в Python 3
AES CFB - как CBC, но без подкладки
Это подход, которому следует All Іs Vаиітy , хотя и неправильно. Это
cryptography
версия, но обратите внимание, что я включаю IV в зашифрованный текст , он не должен храниться как глобальный (повторное использование IV ослабляет безопасность ключа, а его сохранение как глобальный модуль означает, что он будет повторно сгенерирован следующий вызов Python, который делает весь зашифрованный текст не дешифруемым):Здесь отсутствует добавленная защита подписи HMAC и временная метка; вам придется добавить их самостоятельно.
Вышеупомянутое также показывает, насколько легко неправильно комбинировать базовые строительные блоки криптографии; Неправильная обработка значения IV Vaiti может привести к утечке данных или к нечитаемости всех зашифрованных сообщений из-за потери IV. Использование Fernet вместо этого защищает вас от таких ошибок.
AES ECB - небезопасно
Если вы ранее реализовали шифрование AES ECB и вам все еще нужно поддерживать его в Python 3, вы можете сделать это и с
cryptography
. Применяются те же предостережения, что ECB недостаточно безопасен для реальных приложений . Повторная реализация этого ответа для Python 3 с добавлением автоматической обработки заполнения:Опять же, здесь отсутствует подпись HMAC, и вам все равно не следует использовать ECB. Вышеупомянутое просто для иллюстрации того, что
cryptography
может обрабатывать обычные криптографические строительные блоки, даже те, которые вам на самом деле не следует использовать.источник
"Encoded_c", упомянутый в ответе шифра Виженера @ smehmood, должен быть "key_c".
Здесь работают функции кодирования / декодирования.
Отказ от ответственности: как подразумевается в комментариях, это не должно использоваться для защиты данных в реальном приложении, если вы не читаете это и не против поговорить с юристами:
Что не так с шифрованием XOR?
источник
encodedmsg = encode('mypassword', 'this is the message éçàèç"')
print encodedmsg
print decode('mypassword', encodedmsg)
работает нормально.Вот версия Python 3 функций из @qneill «s ответа :
Дополнительное кодирование / декодирование необходимо, потому что Python 3 разделил массивы строк / байтов на две разные концепции и обновил свои API, чтобы отразить это.
источник
.encode()).decode()
. в возвратеencode()
, а.decode()
во второй строке вdecode()
.Отказ от ответственности: как упоминалось в комментариях, это не должно использоваться для защиты данных в реальном приложении.
Что не так с шифрованием XOR?
/crypto/56281/breaking-a-xor-cipher-of-known-key-length
https://github.com/hellman/xortool
Как уже упоминалось, библиотека PyCrypto содержит набор шифров. «Шифр» XOR можно использовать для грязной работы, если вы не хотите делать это самостоятельно:
Шифр работает следующим образом без дополнения открытого текста:
Кредит на https://stackoverflow.com/a/2490376/241294 для функций кодирования / декодирования base64 (я новичок в Python).
источник
sudo pip3 install pycrypto
,Вот реализация безопасного шифрования и дешифрования URL-адресов с использованием AES (PyCrypto) и base64.
Если вы столкнулись с такой проблемой, как эта, https://bugs.python.org/issue4329 (
TypeError: character mapping must return integer, None or unicode
) используйтеstr(cipher)
при декодировании следующим образом:Тест:
источник
TypeError: Object type <class 'str'> cannot be passed to C code
.b'...'
, я отредактировал ответ для использования в будущем!Рабочие функции кодирования / декодирования в python3 (очень мало адаптированы из ответа qneill):
источник
Спасибо за отличные ответы. Ничего оригинального, чтобы добавить, но вот несколько прогрессивных переписываний ответа qneill с использованием некоторых полезных средств Python. Надеюсь, вы согласны, что они упрощают и уточняют код.
источник
Если вы хотите быть в безопасности, вы можете использовать Fernet, который криптографически надежен. Вы можете использовать статическую «соль», если не хотите хранить ее отдельно - вы потеряете только словарь и защиту от радужных атак. Я выбрал его, потому что могу выбирать длинные или короткие пароли, что с AES не так просто.
Если это слишком сложно, кто-то предложил simplecrypt
источник
Кто бы ни пришел сюда (и щедрый), похоже, искал однострочные с небольшой настройкой, чего не предоставляют другие ответы. Так что выдвигаю base64.
Теперь имейте в виду, что это только базовая обфускация, и она ** НЕ МОЖЕТ БЕЗОПАСНОСТИ ** , но вот некоторые однострочные:
Несколько замечаний:
bytes()
иbytes::decode()
=
символами. Такие люди, как я, просто расшифровывают их в консоли javascript, когда мы видим их на веб-сайтах. Это так же просто, какbtoa(string)
(js)Теперь, если вам нужен даже не какой-либо ключ, а просто некоторая обфускация, вы снова можете просто использовать base64 без каких-либо ключей:
источник
Fernet(key).encrypt(message)
это всего лишь одно выражение, подобное вашему вызову base64.key
совсем. Множество разработчиков будут копировать и вставлять из Stack Overflow, не обращая внимания, и будут считать, что ключ секретный. Если вы должны включить его, то, по крайней мере, не используйте его и предупреждайте или вызывайте исключение, если оно все равно используется. Не стоит недооценивать глупость культуры копирования и вставки и свою ответственность за выполнение разумных функций.Приведу 4 решения:
1) Использование шифрования Fernet с
cryptography
библиотекойВот решение с использованием пакета
cryptography
, которое вы можете установить как обычноpip install cryptography
:Вы можете адаптироваться со своей собственной солью, количеством итераций и т. Д. Этот код не очень далеко от ответа @ HCLivess, но цель здесь - иметь готовые к использованию
encrypt
иdecrypt
функции. Источник: https://cryptography.io/en/latest/fernet/#using-passwords-with-fernet .Примечание: используйте
.encode()
и.decode()
везде, если вам нужны строки'John Doe'
вместо байтов, напримерb'John Doe'
.2) Простое шифрование AES с
Crypto
библиотекойЭто работает с Python 3:
Примечание: вы можете удалить
base64.b64encode
и,.b64decode
если вы не хотите выводить текст в читаемом виде и / или если вы все равно хотите сохранить зашифрованный текст на диск в виде двоичного файла.3) AES с использованием улучшенной функции создания ключа пароля и возможности проверки «введен ли неправильный пароль» с помощью
Crypto
библиотекиРешение 2) с AES "режимом CFB" нормально, но имеет два недостатка: тот факт, что
SHA256(password)
его можно легко перебрать с помощью поисковой таблицы, и то, что нет возможности проверить, был ли введен неправильный пароль. Здесь это решается использованием AES в «режиме GCM», как обсуждалось в AES: как определить, что был введен неверный пароль? и Безопасен ли этот способ сказать «Вы ввели неправильный пароль»? :4) Использование RC4 (библиотека не требуется)
Взято из https://github.com/bozhu/RC4-Python/blob/master/rc4.py .
(Устарело с момента последних правок, но сохранено для справки в будущем): у меня были проблемы с использованием Windows + Python 3.6 + все ответы, связанные
pycrypto
(не вpip install pycrypto
Windows) илиpycryptodome
(ответы здесь сfrom Crypto.Cipher import XOR
ошибкой, потому чтоXOR
не поддерживается этойpycrypto
вилкой; и решения с использованием... AES
тоже потерпели неудачу сTypeError: Object type <class 'str'> cannot be passed to C code
). Кроме того, у библиотекиsimple-crypt
естьpycrypto
зависимость, поэтому это не вариант.источник
password_encrypt()
.Это работает, но длина пароля должна быть точной
8
. Это просто и требует pyDes .ВЫВОД:
источник
Другая реализация кода @qneill, включающая контрольную сумму CRC исходного сообщения, выдает исключение, если проверка не удалась:
источник
Вы можете использовать AES для шифрования вашей строки паролем. Тем не менее, вы захотите выбрать достаточно надежный пароль, чтобы люди не могли легко угадать, что это (извините, я ничего не могу с собой поделать. Я подражатель безопасности).
AES отличается хорошим размером ключа, но его также легко использовать с PyCrypto.
источник
Внешние библиотеки предоставляют алгоритмы шифрования с секретным ключом.
Например,
Cypher
модуль PyCrypto предлагает выбор из множества алгоритмов шифрования:Crypto.Cipher.AES
Crypto.Cipher.ARC2
Crypto.Cipher.ARC4
Crypto.Cipher.Blowfish
Crypto.Cipher.CAST
Crypto.Cipher.DES
Crypto.Cipher.DES3
Crypto.Cipher.IDEA
Crypto.Cipher.RC5
Crypto.Cipher.XOR
MeTooCrypto - это
Python
оболочка для OpenSSL , которая предоставляет (помимо других функций) полнофункциональную библиотеку криптографии общего назначения. Включены симметричные шифры (например, AES).источник
если вы хотите безопасное шифрование:
для python 2 вы должны использовать keyczar http://www.keyczar.org/
для python 3, пока не будет доступен keyczar, я написал simple-crypt http://pypi.python.org/pypi/simple-crypt
оба они будут использовать усиление ключа, что сделает их более безопасными, чем большинство других ответов здесь. и поскольку они настолько просты в использовании, вы можете использовать их, даже когда безопасность не является критичной ...
источник
Итак, поскольку ничего критически важного не кодируется , и вы просто хотите зашифровать для обфускации .
Позвольте представить шифр цезаря
Шифр Цезаря или сдвиг Цезаря - один из самых простых и широко известных методов шифрования. Это тип шифра подстановки, в котором каждая буква в открытом тексте заменяется буквой на фиксированное количество позиций в алфавите. Например, при сдвиге влево 3 D будет заменено на A, E станет B и так далее.
Пример кода для справки:
Достоинства: он отвечает вашим требованиям, прост и выполняет функции кодирования.
Недостаток: может быть взломан простыми алгоритмами грубой силы (маловероятно, что кто-то попытается пройти через все дополнительные результаты).
источник
Добавление еще одного кода с декодированием и кодированием для справки
источник