encriptar - encrypt string python 3
¿Una forma simple de codificar una cadena de acuerdo con una contraseña? (15)
A medida que explícitamente declaras que quieres oscuridad y no seguridad, evitaremos reprenderte por la debilidad de lo que sugieres :)
Entonces, usando 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()
Si alguien retiene su base de datos y su código base, podrá decodificar los datos encriptados. ¡Mantenga su secret_key segura!
¿Tiene Python una forma simple e integrada de codificar / decodificar cadenas usando una contraseña?
Algo como esto:
>>> encode(''John Doe'', password = ''mypass'')
''sjkl28cn2sx0''
>>> decode(''sjkl28cn2sx0'', password = ''mypass'')
''John Doe''
Entonces la cadena "John Doe" se cifra como ''sjkl28cn2sx0''. Para obtener la cadena original, "desbloquearía" esa cadena con la clave ''mypass'', que es una contraseña en mi código fuente. Me gustaría que esta sea la forma en que puedo cifrar / descifrar un documento de Word con una contraseña.
Me gustaría usar estas cadenas encriptadas como parámetros de URL. Mi objetivo es la ofuscación, no la seguridad fuerte; nada de misión crítica está siendo codificado. Me doy cuenta de que podría usar una tabla de base de datos para almacenar claves y valores, pero trato de ser minimalista.
Aquí hay una implementación de cifrado y descifrado de URL segura usando AES (PyCrypto) y base64.
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))
Si enfrenta algún problema como este https://bugs.python.org/issue4329 (TypeError: la asignación de caracteres debe devolver un entero, None o unicode) use str (cipher) mientras se descodifica de la siguiente manera
return obj2.decrypt (base64.urlsafe_b64decode (str (cifra)))
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
Aquí hay una versión de Python 3 de las funciones de la respuesta de @qneill:
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)
Las codificaciones / decodificaciones adicionales son necesarias porque Python 3 ha dividido matrices de cadenas / bytes en dos conceptos diferentes y ha actualizado sus API para reflejar eso.
Asumiendo que solo está buscando una ofuscación simple que oscurecerá las cosas del observador casual, y que no busca utilizar bibliotecas de terceros. Yo recomendaría algo así como el cifrado Vigenere. Es uno de los cifrados antiguos simples más potentes.
Es rápido y fácil de implementar. Algo como:
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)
Decode es más o menos lo mismo, excepto que restas la clave.
Es mucho más difícil de romper si las cadenas que está codificando son cortas, y / o si es difícil adivinar la longitud de la frase de contraseña utilizada.
Si está buscando algo criptográfico, PyCrypto es probablemente su mejor opción, aunque las respuestas anteriores pasan por alto algunos detalles: el modo ECB en PyCrypto requiere que su mensaje sea un múltiplo de 16 caracteres de longitud. Entonces, debes rellenar. Además, si desea usarlos como parámetros de URL, use base64.urlsafe_b64_encode()
, en lugar del estándar. Esto reemplaza algunos de los caracteres del alfabeto base64 con caracteres seguros para URL (como su nombre lo sugiere).
Sin embargo, debe estar ABSOLUTAMENTE seguro de que esta delgada capa de ofuscación es suficiente para sus necesidades antes de usar esto. El artículo de Wikipedia al que se vinculó proporciona instrucciones detalladas para descifrar el cifrado, por lo que cualquier persona con una cantidad moderada de determinación podría romperlo fácilmente.
Como se ha mencionado, la biblioteca PyCrypto contiene un conjunto de cifras. El cifrado XOR se puede usar para hacer el trabajo sucio si no quieres hacerlo tú mismo:
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))
Aunque solo proporciona una seguridad mínima, aún recomiendo usar una clave de aspecto aleatorio sin ningún espacio de caracteres (ya que XOR es un carácter ASCII [a-zA-Z] con un espacio que simplemente voltea la caja).
El cifrado funciona de la siguiente manera sin tener que rellenar el texto sin formato:
>>> encrypt(''notsosecretkey'', ''Attack at dawn!'')
''LxsAEgwYRQIGRRAKEhdP''
>>> decrypt(''notsosecretkey'', encrypt(''notsosecretkey'', ''Attack at dawn!''))
''Attack at dawn!''
Crédito a https://.com/a/2490376/241294 para las funciones de codificación / decodificación base64 (soy un novato de python).
El "encoded_c" mencionado en la respuesta de cifrado Vigenere de @ smehmood debe ser "key_c".
Aquí están trabajando las funciones de codificación / decodificación.
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)
Esto funciona, pero la longitud de la contraseña debe ser exactamente 8
. Esto es simple y requiere 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
SALIDA:
³./Þ/åS¾+æÅ`;Ê
John Doe
Funciones de codificación / descodificación de trabajo en python3 (muy poco adaptado de la respuesta de Qneill):
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)
Gracias por algunas buenas respuestas. Nada original para agregar, pero aquí hay algunas reescrituras progresivas de la respuesta de qneill usando algunas instalaciones útiles de Python. Espero que acepten que simplifican y aclaran el código.
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()
- empareja los elementos en una lista con su índiceiterar sobre los personajes en una cadena
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)
compilar listas usando una lista de comprensión
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)
A menudo, en Python no hay necesidad de índices de listas en absoluto. Elimine las variables de índice de bucle por completo usando zip y ciclo:
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)
y algunas pruebas ...
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
Las bibliotecas externas proporcionan algoritmos de cifrado de clave secreta.
Por ejemplo, el módulo Cypher
en PyCrypto ofrece una selección de muchos algoritmos de encriptación:
-
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 es un contenedor de Python
para OpenSSL , y proporciona (entre otras funciones) una biblioteca de criptografía de uso general con todas las funciones. Se incluyen cifrados simétricos (como AES).
Otra implementación del código @qneill que incluye una suma de verificación CRC del mensaje original arroja una excepción si la verificación falla:
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
Puede usar AES para cifrar su cadena con una contraseña. Sin embargo, querrás elegir una contraseña lo suficientemente fuerte para que la gente no adivine fácilmente de qué se trata (lo siento, no puedo evitarlo. Soy un fanático de la seguridad).
AES es fuerte con un buen tamaño de clave, pero también es fácil de usar con PyCrypto.
Si quiere estar seguro, puede usar Fernet, que es criptográficamente sólido. Puede utilizar una "sal" estática si no desea almacenarla por separado: solo perderá la prevención de ataques de diccionario y arco iris. Lo elegí porque puedo elegir contraseñas largas o cortas ", lo cual no es tan fácil con 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
Si eso es demasiado complicado, alguien sugirió Simlecrypt
from simplecrypt import encrypt, decrypt
ciphertext = encrypt(''password'', plaintext)
plaintext = decrypt(''password'', ciphertext)
Una forma simple es usar la biblioteca, y PyCrypto es el bueno.
si quieres cifrado seguro:
para Python 2, debes usar keyczar http://www.keyczar.org/
para python 3, hasta que keyczar esté disponible, he escrito simple-crypt http://pypi.python.org/pypi/simple-crypt
ambos utilizarán el fortalecimiento de clave que los hace más seguros que la mayoría de las otras respuestas aquí. y dado que son tan fáciles de usar, es posible que desee utilizarlos incluso cuando la seguridad no es crítica ...