La version Node.js de chiffrement et de déchiffrement AES-CBC avec Python sera également ajoutée.

Flux de programme d'exemple (cryptage AES, décryptage)

Tout d'abord, installez la bibliothèque

pip install pycrypto

Côté client (côté cryptage dans l'exemple de programme)

.Vecteur initial (16 octets), clé Lors de l'utilisation de + α PBKDF, un mot de passe pour générer une clé dérivée est également préparé. .Encryption → Des données binaires peuvent être créées Convertissez les données binaires (données cryptées) en Base64 ou en nombre hexadécimal, convertissez-les en format encodé en URL et envoyez-les au serveur

Côté serveur (côté complexe dans l'exemple de programme)

Décodage .URL .Conversion des nombres Base64 et hexadécimaux en binaire Préparez le même vecteur initial, la même clé, etc. que le côté crypté. Plutôt que d'avoir le vecteur initial comme valeur fixe, il est plus sûr d'en générer un différent à chaque fois par une méthode que seuls le côté de cryptage et le côté de décryptage peuvent connaître. . Composite

Points et précautions

Préparez le vecteur initial, le sel et le mot de passe. Il est recommandé que le vecteur initial soit généré aléatoirement à chaque fois plutôt qu'une valeur fixe.

Ici, à titre d'exemple, le vecteur initial est digéré avec l'horodatage actuel → affiché en hexadécimal → sha512. J'ai pensé à la méthode de génération de manière appropriée pour saisir tout le flux.

*** Veuillez ne pas utiliser le vecteur initial, le sel et le mot de passe tels quels. *** ***

Côté client (personne à crypter)


# -*- coding: utf-8 -*-
import base64
import urllib.parse
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Util import Padding
import requests
from datetime import datetime,timedelta,timezone
import hashlib

#Créer un vecteur initial(J'ai pensé à la méthode de génération comme si je l'utilisais pour sha512.)Comme il est converti en octets de type hexadécimal, le nombre de caractères doit être pair.
JST = timezone(timedelta(hours=9),"JST")
now = hex(int(datetime.now(JST).timestamp()))
hs = hashlib.sha512(now.encode()).hexdigest()
hex_iv = hs[0:100]
#Puisqu'il est converti en octets hexadécimaux de type sel, le nombre de caractères doit être pair.
hex_salt = "39ccc779ab356eb43b4f37aedbc891d2f891756710b7856d21a2fd691483fb17"
secret_key = "asd@dfdfdsds"


def encrypt(plainText):
    #La longueur du vecteur initial doit être de 16 octets
    iv = bytes.fromhex(hex_iv)[:AES.block_size]
    #Nombre d'étirements Plus ce nombre est élevé, plus la force de cryptage est forte et plus la vitesse d'exécution du cryptage / décryptage est lente.
    secure_levels = 100
    #Il n'y a pas de restrictions particulières sur la longueur du sel
    salt = bytes.fromhex(hex_salt)
    
    #Génération de clé dérivée Dans le cas d'AES, la longueur de clé est de 16 octets(AES-128), 24 bytes(AES-192), 32bytes(AES-256)Doit être l'un des
    key = PBKDF2(password=secret_key, salt=salt, dkLen=16, count=secure_levels)
    
    #Création de chiffrement
    cipher = AES.new(key, AES.MODE_CBC, iv)

    #Rembourrage
    data = plainText.encode()
    padding = AES.block_size - len(data) % AES.block_size
    data += (chr(padding) * padding).encode()

    #chiffrement
    encrypted = cipher.encrypt(data)
    
    print(f"encrypted = {encrypted}\n")
    
    #binary to HEX
    hex_data = encrypted.hex()
    print(f"hex_data : binary to HEX = {hex_data}\n")

    #Encodage Base64
    base64_encoded = base64.b64encode(hex_data.encode())
    print(f"base64_encoded : Hex to Base64 = {base64_encoded.decode()}\n")

    #Encodage URL Non requis cette fois, mais encodage URL chaque fois que nécessaire
    # url_encoded = urllib.parse.quote(base64_encoded)

    return base64_encoded


if __name__ == "__main__":
    plainText = "Testez le cryptage."
    print(f"\nPlain text = {plainText}\n")
    
    #chiffrement
    encrypted = encrypt(plainText)

    #Envoyer
    requests.get("http://localhost:5000/get",params={"text" : encrypted,"now" : now})

Côté serveur (complexe)


# -*- coding: utf-8 -*-
import base64
import json
import urllib.parse
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Util import Padding
from flask import Flask, render_template, request
import hashlib

app = Flask(__name__)


#Nombre hexadécimal de sel. Comme il sera converti en octets de type, le nombre de caractères doit être pair
hex_salt = "39ccc779ab356eb43b4f37aedbc891d2f891756710b7856d21a2fd691483fb17"
secret_key = "asd@dfdfdsds"


def decrypt(base64encoded_value,now):
    #Décodage d'URL Non requis cette fois, mais décodage d'URL à tout moment si nécessaire dans d'autres langues, etc.
    # url_decoded = urllib.parse.unquote(base64encoded_value)
    # print(f"url_decoded = {url_decoded}")

    #Décodage en base64
    hex_data = base64.b64decode(base64encoded_value).decode()
    print(f"hex_data : Base64 to Hex = {hex_data}\n")

    # HEX → binary
    encrypted_data = bytes.fromhex(hex_data)
    print(f"encrypted_data : Hex to binary = {encrypted_data}\n")

    #La longueur du vecteur initial doit être de 16 octets
    hs = hashlib.sha512(now.encode()).hexdigest()
    hex_iv = hs[0:100]
    iv = bytes.fromhex(hex_iv)[:AES.block_size]
    #Nombre d'étirements Plus ce nombre est élevé, plus la force de cryptage est forte et plus la vitesse d'exécution du cryptage / décryptage est lente.
    secure_levels = 100
    #Il n'y a pas de restrictions particulières sur la longueur du sel
    salt = bytes.fromhex(hex_salt)

    #Génération de clé dérivée
    key = PBKDF2(password=secret_key, salt=salt, dkLen=16, count=secure_levels)

    #Création de chiffrement
    cipher = AES.new(key, AES.MODE_CBC, iv)

    #Composite
    decrypted = cipher.decrypt(encrypted_data)

    #Décompresser
    response = decrypted[0: -int(decrypted[-1])].decode('utf-8')
    return response

#Obtenir le paramètre Obtenir
@app.route('/get')
def get():
    text = ""
    if "text" not in request.args or "now" not in request.args:
        return json.dumps({"message": "send message"})

    base64encoded_value = request.args.get('text')
    now = request.args.get('now')
    print(f"\nbase64encoded_value = {base64encoded_value}\n")
       
    #Décryptage
    decrypted_data = decrypt(base64encoded_value,now)
    print(f"decrypted_data = {decrypted_data}\n")        

    return json.dumps({"message": "OK"})


if __name__ == "__main__":
    app.run(host='0.0.0.0',port=5000)

Recommended Posts

La version Node.js de chiffrement et de déchiffrement AES-CBC avec Python sera également ajoutée.
Chiffrement et déchiffrement avec Python
LiNGAM (version ICA) à comprendre avec des formules mathématiques et Python
Gestion des versions de Node, Ruby et Python avec anyenv
cryptage et décryptage pycrypto
Vérifier la version avec python
Procédure d'installation pour Python et Ansible avec une version spécifique
Essayez le chiffrement / déchiffrement à l'aide de la clé OpenSSL avec la fonction pow de Python3
Programmation avec Python et Tkinter
Python et matériel - Utilisation de RS232C avec Python -
python avec pyenv et venv
Spécifiez la version python avec virtualenv
Fonctionne avec Python et R
Crypter / décrypter avec la commande GPG