简单的方法来编码一个string根据密码?
Python是否有一个内置的,使用密码编码/解码string的简单方法?
像这样的东西:
>>> encode('John Doe', password = 'mypass') 'sjkl28cn2sx0' >>> decode('sjkl28cn2sx0', password = 'mypass') 'John Doe'
所以string“John Doe”被encryption为“sjkl28cn2sx0”。 为了得到原始的string,我会用“mypass”这个密钥在我的源代码中“解锁”这个string。 我想这是我可以使用密码encryption/解密Word文档的方式。
我想使用这些encryption的string作为URL参数。 我的目标是混淆,不是强大的安全; 没有任何关键的编码。 我意识到我可以使用一个数据库表来存储键和值,但我试图是极简主义的。
假设你只是在寻找简单的模糊处理,这会使非常随意的观察者变得模糊,而你并不想使用第三方库。 我会推荐像Vigenere密码。 它是简单的古代密码中最强大的一个。
https://en.wikipedia.org/wiki/Vigenère_cipher
这是快速和容易实施。 就像是:
import base64 def encode(key, string): encoded_chars = [] for i in xrange(len(string)): key_c = key[i % len(key)] encoded_c = chr(ord(string[i]) + ord(key_c) % 256) encoded_chars.append(encoded_c) encoded_string = "".join(encoded_chars) return base64.urlsafe_b64encode(encoded_string)
解码几乎是相同的,除了你减去密钥。
如果你正在编码的string很短,或者很难猜测所使用的密码长度,就很难打破。
如果您正在寻找密码学,PyCrypto可能是您最好的select,尽pipe以前的答案忽略了一些细节:PyCyrpto中的ECB模式要求您的消息长度为16个字符的倍数。 所以,你必须垫。 另外,如果您想将它们用作URL参数,请使用base64.urlsafe_b64_encode()
,而不是标准的。 这将使用URL安全字符replacebase64字母表中的一些字符(如其名称所示)。
但是,在使用这个之前,应该绝对确定这个非常薄的混淆层就足以满足您的需求。 我链接到的维基百科文章提供了关于破译密码的详细说明,所以任何具有适度决定的人都可以轻易破解它。
正如你明确表示你想隐晦不安全,我们将避免谴责你的弱点你build议:)
所以,使用PyCrypto:
from Crypto.Cipher import AES import base64 msg_text = 'test some plain text here'.rjust(32) secret_key = '1234567890123456' # create new & store somewhere safe cipher = AES.new(secret_key,AES.MODE_ECB) # never use ECB in strong systems obviously encoded = base64.b64encode(cipher.encrypt(msg_text)) # ... decoded = cipher.decrypt(base64.b64decode(encoded)) print decoded.strip()
如果有人拿到你的数据库和你的代码库,他们将能够解码encryption的数据。 保持你的秘密密钥安全!
@ smehmood的Vigenere密码答案中提到的“encoded_c”应该是“key_c”。
这里是工作编码/解码function。
import base64 def encode(key, clear): enc = [] for i in range(len(clear)): key_c = key[i % len(key)] enc_c = chr((ord(clear[i]) + ord(key_c)) % 256) enc.append(enc_c) return base64.urlsafe_b64encode("".join(enc)) def decode(key, enc): dec = [] enc = base64.urlsafe_b64decode(enc) for i in range(len(enc)): key_c = key[i % len(key)] dec_c = chr((256 + ord(enc[i]) - ord(key_c)) % 256) dec.append(dec_c) return "".join(dec)
以下是@qneill的答案的Python 3版本的function:
import base64 def encode(key, clear): enc = [] for i in range(len(clear)): key_c = key[i % len(key)] enc_c = chr((ord(clear[i]) + ord(key_c)) % 256) enc.append(enc_c) return base64.urlsafe_b64encode("".join(enc).encode()).decode() def decode(key, enc): dec = [] enc = base64.urlsafe_b64decode(enc).decode() for i in range(len(enc)): key_c = key[i % len(key)] dec_c = chr((256 + ord(enc[i]) - ord(key_c)) % 256) dec.append(dec_c) return "".join(dec)
额外的编码/解码是需要的,因为Python 3已经将string/字节数组拆分为两个不同的概念,并更新了它们的API来反映这些。
如前所述,PyCrypto库包含一套密码。 如果你不想自己动手的话,XOR密码可以用来做肮脏的工作:
from Crypto.Cipher import XOR import base64 def encrypt(key, plaintext): cipher = XOR.new(key) return base64.b64encode(cipher.encrypt(plaintext)) def decrypt(key, ciphertext): cipher = XOR.new(key) return cipher.decrypt(base64.b64decode(ciphertext))
尽pipe它只提供了最小的安全性,但我仍然build议使用一个没有任何空格字符的随机查找键(因为用一个空格对一个ASCII [a-zA-Z]字符进行异或操作就可以翻转)。
密码的工作原理如下,无需填充明文:
>>> encrypt('notsosecretkey', 'Attack at dawn!') 'LxsAEgwYRQIGRRAKEhdP' >>> decrypt('notsosecretkey', encrypt('notsosecretkey', 'Attack at dawn!')) 'Attack at dawn!'
感谢https://stackoverflow.com/a/2490376/241294为base64编码/解码function(我是一个python新手)。;
这是一个使用AES(PyCrypto)和base64实现的URL安全encryption和解密。
import base64 from Crypto import Random from Crypto.Cipher import AES AKEY = 'mysixteenbytekey' # AES key must be either 16, 24, or 32 bytes long iv = Random.new().read(AES.block_size) def encode(message): obj = AES.new(AKEY, AES.MODE_CFB, iv) return base64.urlsafe_b64encode(obj.encrypt(message)) def decode(cipher): obj2 = AES.new(AKEY, AES.MODE_CFB, iv) return obj2.decrypt(base64.urlsafe_b64decode(cipher)) In [13]: encode("Hello World") Out[13]: b'67jjg-8_RyaJ-28=' In [14]: %timeit encode("Hello World") 100000 loops, best of 3: 13.9 µs per loop In [15]: decode(b'67jjg-8_RyaJ-28=') Out[15]: b'Hello World' In [16]: %timeit decode(b'67jjg-8_RyaJ-28=') 100000 loops, best of 3: 15.2 µs per loop
在python3中使用编码/解码函数(qneill的答案很less适应):
def encode(key, clear): enc = [] for i in range(len(clear)): key_c = key[i % len(key)] enc_c = (ord(clear[i]) + ord(key_c)) % 256 enc.append(enc_c) return base64.urlsafe_b64encode(bytes(enc)) def decode(key, enc): dec = [] enc = base64.urlsafe_b64decode(enc) for i in range(len(enc)): key_c = key[i % len(key)] dec_c = chr((256 + enc[i] - ord(key_c)) % 256) dec.append(dec_c) return "".join(dec)
简单的方法是使用库, PyCrypto是最好的。
这工作,但密码长度应该是8
。 这很简单,需要pyDes 。
from pyDes import * def encode(data,password): k = des(password, CBC, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5) d = k.encrypt(data) return d def decode(data,password): k = des(password, CBC, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5) d = k.decrypt(data) return d x = encode('John Doe', 'mypass12') y = decode(x,'mypass12') print x print y
OUTPUT:
³.\Þ\åS¾+æÅ`;Ê John Doe
外部库提供秘密密钥encryptionalgorithm。
例如, PyCrypto中的Cypher
模块提供了许多encryptionalgorithm的select:
-
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是OpenSSL的Python
包装器,并提供了一个全function的通用密码库。 包括对称密码(如AES)。
如果你想要安全encryption:
对于Python 2,你应该使用keyczar http://www.keyczar.org/
对于python 3,直到keyczar可用,我已经写了simple-crypt http://pypi.python.org/pypi/simple-crypt
这两个将使用关键加强,这使得他们比这里的大多数其他答案更安全。 而且由于它们非常易于使用,所以即使在安全性不重要的情况下也可能要使用它们。
感谢一些很好的答案。 没有什么原创的补充,但这里是一些渐进式的重写使用一些有用的Python工具qneill的答案。 我希望你们同意他们简化和澄清代码。
import base64 def qneill_encode(key, clear): enc = [] for i in range(len(clear)): key_c = key[i % len(key)] enc_c = chr((ord(clear[i]) + ord(key_c)) % 256) enc.append(enc_c) return base64.urlsafe_b64encode("".join(enc)) def qneill_decode(key, enc): dec = [] enc = base64.urlsafe_b64decode(enc) for i in range(len(enc)): key_c = key[i % len(key)] dec_c = chr((256 + ord(enc[i]) - ord(key_c)) % 256) dec.append(dec_c) return "".join(dec)
enumerate()
– 列表中的项目与他们的索引迭代string中的字符
def encode_enumerate(key, clear): enc = [] for i, ch in enumerate(clear): key_c = key[i % len(key)] enc_c = chr((ord(ch) + ord(key_c)) % 256) enc.append(enc_c) return base64.urlsafe_b64encode("".join(enc)) def decode_enumerate(key, enc): dec = [] enc = base64.urlsafe_b64decode(enc) for i, ch in enumerate(enc): key_c = key[i % len(key)] dec_c = chr((256 + ord(ch) - ord(key_c)) % 256) dec.append(dec_c) return "".join(dec)
使用列表理解build立列表
def encode_comprehension(key, clear): enc = [chr((ord(clear_char) + ord(key[i % len(key)])) % 256) for i, clear_char in enumerate(clear)] return base64.urlsafe_b64encode("".join(enc)) def decode_comprehension(key, enc): enc = base64.urlsafe_b64decode(enc) dec = [chr((256 + ord(ch) - ord(key[i % len(key)])) % 256) for i, ch in enumerate(enc)] return "".join(dec)
通常在Python中,根本不需要列表索引。 完全使用zip和循环消除循环索引variables:
from itertools import cycle def encode_zip_cycle(key, clear): enc = [chr((ord(clear_char) + ord(key_char)) % 256) for clear_char, key_char in zip(clear, cycle(key))] return base64.urlsafe_b64encode("".join(enc)) def decode_zip_cycle(key, enc): enc = base64.urlsafe_b64decode(enc) dec = [chr((256 + ord(enc_char) - ord(key_char)) % 256) for enc_char, key_char in zip(enc, cycle(key))] return "".join(dec)
和一些testing…
msg = 'The quick brown fox jumps over the lazy dog.' key = 'jMG6JV3QdtRh3EhCHWUi' print('cleartext: {0}'.format(msg)) print('ciphertext: {0}'.format(encode_zip_cycle(key, msg))) encoders = [qneill_encode, encode_enumerate, encode_comprehension, encode_zip_cycle] decoders = [qneill_decode, decode_enumerate, decode_comprehension, decode_zip_cycle] # round-trip check for each pair of implementations matched_pairs = zip(encoders, decoders) assert all([decode(key, encode(key, msg)) == msg for encode, decode in matched_pairs]) print('Round-trips for encoder-decoder pairs: all tests passed') # round-trip applying each kind of decode to each kind of encode to prove equivalent from itertools import product all_combinations = product(encoders, decoders) assert all(decode(key, encode(key, msg)) == msg for encode, decode in all_combinations) print('Each encoder and decoder can be swapped with any other: all tests passed') >>> python crypt.py cleartext: The quick brown fox jumps over the lazy dog. ciphertext: vrWsVrvLnLTPlLTaorzWY67GzYnUwrSmvXaix8nmctybqoivqdHOic68rmQ= Round-trips for encoder-decoder pairs: all tests passed Each encoder and decoder can be swapped with any other: all tests passed
如果你使用的是密码,最好是正确的(特别是如果你正在处理用户密码的话)。
你想要做的是“encryption”密码,而不是编码。
你有两个select,你可以做到这一点,这取决于谁是encryption的。
如果它是可信的第三方,则使用公钥/私钥encryption。 RSA是一个不错的select。 你把公钥交给你信任的第三方,并保证私钥的安全。
如果你正在做自己的encryption,没有人可以访问你的代码,那么对称密钥encryption是好的。 我推荐一个足够强大的密钥(256位)的AES。
有Python的库可以执行这些encryptionscheme。
你可以安全1/2屁股,但不要。 这不是一个好主意。 永远。
您可以使用AES来使用密码encryption您的string。 虽然,你会想要select一个足够强大的密码,所以人们不能轻易猜出它是什么(抱歉,我不能帮助它,我是一个想要安全的weenie)。
AES密钥很好,但PyCrypto也很容易使用。
@qneill代码的其他实现包括原始消息的CRC校验和,如果检查失败,则会抛出exception:
import hashlib import struct import zlib def vigenere_encode(text, key): text = '{}{}'.format(text, struct.pack('i', zlib.crc32(text))) enc = [] for i in range(len(text)): key_c = key[i % len(key)] enc_c = chr((ord(text[i]) + ord(key_c)) % 256) enc.append(enc_c) return base64.urlsafe_b64encode("".join(enc)) def vigenere_decode(encoded_text, key): dec = [] encoded_text = base64.urlsafe_b64decode(encoded_text) for i in range(len(encoded_text)): key_c = key[i % len(key)] dec_c = chr((256 + ord(encoded_text[i]) - ord(key_c)) % 256) dec.append(dec_c) dec = "".join(dec) checksum = dec[-4:] dec = dec[:-4] assert zlib.crc32(dec) == struct.unpack('i', checksum)[0], 'Decode Checksum Error' return dec
如果你想要安全,你可以使用Fernet,这是密码良好的。 如果你不想单独存储,你可以使用静态的“salt” – 你只会丢失词典和彩虹攻击防范。 我select它是因为我可以select长或短的密码,这对于AES来说并不那么容易。
from cryptography.fernet import Fernet from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC import base64 #set password password = "mysecretpassword" #set message message = "secretmessage" kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt="staticsalt", iterations=100000, backend=default_backend()) key = base64.urlsafe_b64encode(kdf.derive(password)) f = Fernet(key) #encrypt encrypted = f.encrypt(message) print encrypted #decrypt decrypted = f.decrypt(encrypted) print decrypted
如果这太复杂,有人build议simplecrypt
from simplecrypt import encrypt, decrypt ciphertext = encrypt('password', plaintext) plaintext = decrypt('password', ciphertext)