Utilisez un module de cryptographie qui gère OpenSSL en Python

introduction

** cryptographie ** est un module Python qui encapsule OpenSSL. Avec des interfaces de haut niveau et de bas niveau, vous pouvez gérer tout ce que vous voulez avec OpenSSL. https://cryptography.io/en/latest/

En regardant le code qui gère le chiffrement à clé publique en Python, il semble qu'il y ait de nombreux cas où la commande ʻopenssl` est appelée par le module de sous-processus. Ce n'est pas gênant, mais cela coûte plus cher à chaque fois, il est donc plus rapide d'utiliser des modules lorsque vous traitez de grands nombres.

De plus, même s'il s'agit d'un wrapper, il est beau et agréable que tout ce qui est écrit par l'utilisateur soit du code Python. C'est juste une touche personnelle.

À partir de l'exemple de code en premier

Tout d'abord, jetez un œil à l'exemple de code pour voir à quel point c'est facile. (Résumé de l'exemple de code)

Clé privée

Créer

generate_privkey.py


from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa, ec, ed25519

def generate_privkey(key_type = ''):
    if key_type == 'ec' or key_type == 'ecdsa':
        privkey = ec.generate_private_key(
            ec.SECP256R1(),
            default_backend()
        )
    elif key_type == 'ed25519':
        privkey = ed25519.Ed25519PrivateKey.generate()
    else:
        privkey = rsa.generate_private_key(
            public_exponent=65537,
            key_size=2048,
            backend=default_backend()
        )
    return privkey

Comment le faire dépend de l'algorithme de clé privée. (L'objet clé généré n'a pas la même classe de base, donc mypy se met en colère)

Lis

load_privkey.py


from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization

def load_privkey(filename):
    with open(filename, 'rb') as fpr:
        privkey = serialization.load_pem_private_key(
            fpr.read(),
            password=None,
            backend=default_backend()
        )
    return privkey

La fonction change en fonction du format de fichier. La plupart du temps, je pense que c'est au format PEM (le format qui commence par ----- BEGIN .... -----).

Vous n'êtes pas obligé de connaître l'algorithme clé.

l'écriture

save_privkey.py


from cryptography.hazmat.primitives import serialization

def save_privkey(filename, privkey):
    serialized_key = privkey.private_bytes(
            serialization.Encoding.PEM,
            serialization.PrivateFormat.PKCS8,
            serialization.NoEncryption()
    )
    with open(filename, 'wb') as fpw:
        fpw.write(serialized_key)

Sérialisez la clé privée dans un tableau d'octets. Appelez la méthode private_bytes de l'objet clé, en spécifiant le format et ainsi de suite.

Comme pour la lecture, vous n'avez pas besoin de connaître l'algorithme clé.

Clé publique

Obtenez et écrivez

save_pubkey.py


from cryptography.hazmat.primitives import serialization

def save_pubkey(filename, privkey):
    pubkey = privkey.public_key()
    serialized_key = pubkey.public_bytes(
            serialization.Encoding.PEM,
            serialization.PublicFormat.SubjectPublicKeyInfo
    )
    with open(filename, 'wb') as fpw:
        fpw.write(serialized_key)

Obtenez la clé publique de la clé privée. Le reste est sérialisé de la même manière que la clé privée. La méthode est public_bytes.

Certificat électronique

Créer un CSR

Créez un CSR (Certificate Signing Request). La clé privée privkey utilisée pour la signature spécifie l'objet clé créé dans la section précédente.

make_csr.py


from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes

def make_csr(privkey):
    builder = x509.CertificateSigningRequestBuilder()
    builder = builder.subject_name(
        x509.Name([
            x509.NameAttribute(x509.NameOID.COMMON_NAME, 'example.com'),
        ])
    )
    builder = builder.add_extension(
        x509.SubjectAlternativeName([
            x509.DNSName('www.example.com'),
            x509.DNSName('test.example.com')
            ]
        ),
        critical=False
    )
    return builder.sign(privkey, hashes.SHA256(), default_backend())

C'est facile à faire en utilisant le constructeur.

Points à faire attention lors de l'utilisation

Et ça. Je pense que vous pouvez l'écrire d'une manière facile à comprendre.

Voici quelques points à garder à l'esprit lorsque vous essayez de l'utiliser.

“hazmat”

la cryptographie se compose de deux éléments. L'un est un groupe de modules directement sous "cryptographie" tels que "cryptography.x509" et "cryptography.fernet".

L'autre est un ensemble de modules sous cryptography.hazmat. «Hazmat» est l'abréviation de ** «matières dangereuses» **, et «dangereux» signifie «dangereux». ** Les modules sous Hazmat signifient dangereux **.

En haut du Hazmat Manual,

This is a “Hazardous Materials” module. You should ONLY use it if you’re 100% absolutely sure that you know what you’re doing because this module is full of land mines, dragons, and dinosaurs with laser guns.

est ce qu'il lit. Si vous traduisez la dernière partie avec la traduction Google,

Ce module est plein de mines, de dragons et de dinosaures avec des pistolets laser, alors ne l'utilisez que si vous êtes complètement sûr de ce que vous faites.

C'est une histoire bruyante, mais vous pouvez la considérer comme [^ at_your_own_risk], qui a la même signification que "A vos risques et périls", car c'est un module qui gère le chiffrement et ne peut pas être garanti comme étant suffisamment sécurisé. Je pense que c'est une belle histoire de l'appeler "dinosaure" ou de nommer le module.

[^ at_your_own_risk]: Soyez plus prudent que cela car vous traitez avec la cryptographie.

contraignant

Comme je l'ai mentionné au début, la cryptographie est un wrapper, j'utilise donc la bibliothèque OpenSSL (libssl.so) à l'intérieur. La commande ʻopenssl elle-même utilise également cette bibliothèque, donc si vous pouvez utiliser la commande ʻopenssl, cette bibliothèque est incluse et elle fonctionne très bien.

L'utilisation d'une combinaison de ces langages compilés à partir d'un langage de script est appelée liaison. Vous n'avez pas à vous inquiéter si vous déployez la cryptographie avec pip, mais si vous la déployez d'une manière spéciale [^ lambda] ou dans un environnement spécial, vous pouvez avoir des problèmes. Dans ce cas, je pense qu'il est assez difficile de le résoudre avec seulement une connaissance de Python. Il peut être préférable d'appeler la commande ʻopenssl` plutôt que de chercher une solution.

[^ lambda]: par exemple, si vous effectuez cette opération manuellement pour une utilisation avec Lambda sur AWS.

Environnement d'exploitation

Ceci est également lié à la liaison, mais cela ne fonctionne pas dans les environnements où OpenSSL ne fonctionne pas. De plus, vous ne pouvez installer avec pip que dans les environnements suivants:

Sinon, vous pouvez également le construire vous-même (https://cryptography.io/en/latest/installation/#build-on-linux). À première vue, cela ne semble pas si gênant, mais je me demande si la zone de reliure est gênante.

Résumé

Si vous lisez l'exemple de code, vous constaterez que ce n'est pas si difficile. Je pense que c'est plus facile à gérer pour pythonista, surtout parce qu'il y a des abstractions pythoniques ici et là.

Si vous disposez d'un environnement d'exploitation, pourquoi ne pas l'essayer?

Recommended Posts

Utilisez un module de cryptographie qui gère OpenSSL en Python
Comment utiliser SQLite en Python
Comment utiliser Mysql avec python
Comment utiliser ChemSpider en Python
Comment utiliser PubChem avec Python
Comment gérer le japonais avec Python
[Introduction à Python] Comment utiliser la classe en Python?
Un moyen simple d'utiliser Wikipedia avec Python
Module pour générer le mot N-gramme en Python
Comment utiliser __slots__ dans la classe Python
Comment utiliser les expressions régulières en Python
Comment utiliser is et == en Python
Utilisez config.ini avec Python
Utiliser des dates en Python
Comment utiliser la bibliothèque d'images Python dans la série python3
Utiliser Valgrind avec Python
Résumé de l'utilisation de MNIST avec Python
Gérer le démarquage avec python
Pour ajouter un module à python que vous mettez dans Julialang
Comment utiliser tkinter avec python dans pyenv
Utiliser le profileur en Python
Comment gérer le type datetime dans sqlite3 de python
Utilisez os.getenv pour obtenir des variables d'environnement en Python
[Pour les débutants] Comment utiliser la commande say avec python!
Comment utiliser Raspeye Relay Module Python
J'ai essayé de résumer comment utiliser les pandas de python
Comment utiliser le modèle appris dans Lobe en Python
Je veux utiliser le jeu de données R avec python
Comment gérer JSON en Ruby, Python, JavaScript, PHP
Voyons comment utiliser def en python
Gérer les données ambiantes en Python
Utiliser l'expression let en Python
Utiliser le protocole de mesure avec Python
python3: Comment utiliser la bouteille (2)
Utiliser la fonction de rappel en Python
Utiliser le magasin de paramètres en Python
[Python] Comment utiliser la liste 1
Connectez-vous au site Web en Python
Utiliser le cache HTTP en Python
Utilisez l'ODM de MongoDB avec Python
Gérer les variables d'environnement en Python
Comment utiliser Python Argparse
Utiliser Random Forest avec Python
Utilisez Spyder de Python IDE
Python: comment utiliser pydub
[Python] Comment utiliser checkio
Parler avec Python [synthèse vocale]
Comment développer en Python
[Python] Comment utiliser input ()
Comment utiliser Python lambda
[Python] Comment utiliser virtualenv
python3: Comment utiliser la bouteille (3)
python3: Comment utiliser la bouteille
Gérer les nombres complexes en Python
Publier sur Slack en Python
Comment utiliser les octets Python
Comment utiliser la méthode __call__ dans la classe Python
[Introduction à l'application Udemy Python3 +] 36. Utilisation de In et Not
Comparaison de l'utilisation des fonctions d'ordre supérieur dans Python 2 et 3