182 votes

Comment encoder une chaîne de caractères en fonction d'un mot de passe ?

Python dispose-t-il d'un moyen simple et intégré d'encoder/décoder des chaînes de caractères à l'aide d'un mot de passe ?

Algo así:

>>> encode('John Doe', password = 'mypass')
'sjkl28cn2sx0'
>>> decode('sjkl28cn2sx0', password = 'mypass')
'John Doe'

Ainsi, la chaîne "John Doe" est cryptée sous la forme "sjkl28cn2sx0". Pour obtenir la chaîne originale, je dois la "déverrouiller" avec la clé "mypass", qui est un mot de passe dans mon code source. J'aimerais que ce soit la façon dont je peux crypter/décrypter un document Word avec un mot de passe.

J'aimerais utiliser ces chaînes cryptées comme paramètres d'URL. Mon objectif est l'obscurcissement, pas une sécurité forte ; rien de critique n'est codé. Je sais que je pourrais utiliser une table de base de données pour stocker les clés et les valeurs, mais j'essaie d'être minimaliste.

2voto

YOU Points 44812

La méthode la plus simple consiste à utiliser la bibliothèque, et PyCrypto est le bon.

2voto

ahmed Points 2842

Une autre implémentation du code @qneill qui inclut la somme de contrôle CRC du message original, lève une exception si le contrôle échoue :

import struct
import zlib
import base64

def vigenere_encode(text, key):
    text = text.encode() + struct.pack('i', zlib.crc32(text.encode()))
    enc = []
    for i in range(len(text)):
        key_c = key[i % len(key)]
        enc_c = chr((text[i] + ord(key_c)) % 256)
        enc.append(enc_c)

    enc = ''.join(enc).encode()
    enc = base64.urlsafe_b64encode(enc)

    return enc.decode()

def vigenere_decode(encoded_text, key):
    dec = []
    encoded_text = base64.urlsafe_b64decode(encoded_text).decode()
    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]

    crc = struct.pack('i', zlib.crc32(dec.encode()))
    assert [int(i) for i in crc] == [ord(i) for i in checksum], 'Decode Checksum Error'

    return dec

2voto

Ajout d'un code supplémentaire avec le décodage et l'encodage pour référence

import base64

def encode(key, string):
    encoded_chars = []
    for i in range(len(string)):
        key_c = key[i % len(key)]
        encoded_c = chr(ord(string[i]) + ord(key_c) % 128)
        encoded_chars.append(encoded_c)
    encoded_string = "".join(encoded_chars)
    arr2 = bytes(encoded_string, 'utf-8')
    return base64.urlsafe_b64encode(arr2)

def decode(key, string):
    encoded_chars = []
    string = base64.urlsafe_b64decode(string)
    string = string.decode('utf-8')
    for i in range(len(string)):
        key_c = key[i % len(key)]
        encoded_c = chr(ord(string[i]) - ord(key_c) % 128)
        encoded_chars.append(encoded_c)
    encoded_string = "".join(encoded_chars)
    return encoded_string

def main():
    answer = str(input("EorD"))
    if(answer in ['E']):
        #ENCODE
        file = open("D:\enc.txt")
        line = file.read().replace("\n", " NEWLINEHERE ")
        file.close()
        text = encode("4114458",line)
        fnew = open("D:\\new.txt","w+")
        fnew.write(text.decode('utf-8'))
        fnew.close()
    else:
        #DECODE
        file = open("D:\\new.txt",'r+')
        eline = file.read().replace("NEWLINEHERE","\n")
        file.close()
        print(eline)
        eline = eline.encode('utf-8')
        dtext=decode("4114458",eline)
        print(dtext)
        fnew = open("D:\\newde.txt","w+")
        fnew.write(dtext)
        fnew.close

if __name__ == '__main__':
    main()

1voto

Walulya francis Points 108

Vous pouvez utiliser le nouveau PyCryptodomex PyCrypto est déprécié et n'est plus maintenu depuis un certain temps.

import base64
from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad, unpad
###################
class Cryptor:
    def __init__(self, key):
      self.SECRET_KEY = str(key).encode("utf-8")
      self.BLOCK_SIZE = 32 # Bytes
      self.CIPHER = AES.new(self.SECRET_KEY, AES.MODE_ECB) # never use ECB in strong systems obviously

    def encrypt(self, text):
       text = str(text).encode("utf-8")
       return base64.b64encode(self.CIPHER.encrypt(pad(text, self.BLOCK_SIZE))).decode("utf-8")

    def decrypt(self, encoded_text):
       self.CIPHER = AES.new(self.SECRET_KEY, AES.MODE_ECB)
       return unpad(self.CIPHER.decrypt(base64.b64decode(encoded_text)), self.BLOCK_SIZE).decode("utf-8")

cryptor = Cryptor("1234567890123456")
text = "hello world"
text = cryptor.encrypt(text)
print(text)
print(cryptor.decrypt(text))

REMARQUE : Assurez-vous que votre clé est de 16 octets.

vous pouvez l'installer avec pip install pycryptodomex car c'est la seule version qui est maintenant indépendante de l'ancienne bibliothèque PyCrypto. Note : tous les modules sont installés sous le paquet Cryptodome, par exemple

from Cryptodome.Cipher import AES

Pour en savoir plus sur la documentation officielle, cliquez ici https://www.pycryptodome.org/src/introduction

0voto

gimel Points 30150

Des bibliothèques externes fournissent des algorithmes de cryptage à clé secrète.

Par exemple, le Cypher dans PyCrypto offre une sélection de nombreux algorithmes de cryptage :

  • 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 est un Python pour les OpenSSL et fournit (entre autres fonctions) une bibliothèque complète de cryptographie à usage général. Les algorithmes de chiffrement symétriques (comme l'AES) sont inclus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X