Chiffrement par clé publique, ** Roman **, n'est-ce pas (impression personnelle) </ sub>? Il semble que vous puissiez faire quelque chose d'amusant, comme l'incorporer dans un logiciel développé personnellement, en plus de son côté pratique.
Cependant, dans la mesure où je googlé à peu près, ~~ Je veux copier et coller un enfant de script comme moi ~~ Je ne pouvais pas trouver que l'implémentation qui était extrêmement oscillante sur le côté simple était réunie en un seul endroit, donc pour la pratique vient de le faire.
Je pensais qu'environ 5% pourrait être considéré comme pratique, donc je vais l'écrire simplement en Python et C #, et échanger des données cryptées entre les deux. Si cela peut être fait, par exemple, les données chiffrées côté client (C #) peuvent être déchiffrées côté serveur (Python), de sorte qu'elles peuvent être mises en pratique, quoique un peu.
** Je ne dis pas qu'il existe une meilleure façon de le mettre en pratique. ** **
Avec Anaconda, c'est facile car il contient presque tout et un module de cryptage.
Si vous voulez commencer avec Python seul, installez pycrypto. [^ 1]
[^ 1]: Il existe plusieurs modules avec la même fonction (et les noms des fonctions sont légèrement différents), ce qui semble être une source de confusion lors de la recherche. Ici, nous utiliserons celui qui est livré en standard avec Anaconda.
cmd.exe
pip install -U pycrypto
.NET Core 3.0 ou supérieur (.NET Framework 5.0 RC1) est requis pour que certaines fonctions appliquent .NET Standard 2.1.
CreateKey.py
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
key_length = 1024
def createKey():
key = RSA.generate(key_length)
private_key = key.exportKey().decode('utf-8')
with open(file="private.pem", mode="w", encoding='utf-8') as file_out:
file_out.write(private_key)
public_key = key.publickey().exportKey().decode('utf-8')
with open(file="public.pem", mode="w", encoding='utf-8') as file_out:
file_out.write(public_key)
Cela générera la clé. La variable key_length spécifie 1024 ou plus, mais selon le Manuel pour un autre module similaire, elle devrait être de 2048 ou plus. Recommandé, 1024,2048,3072 devrait être l'un d'entre eux. [^ 2] Cette fois, cela n'a pas besoin d'être long, donc 1024.
La clé générée est enregistrée séparément en tant que clé privée et clé publique. [^ 3]
[^ 2]: manuel pycrypto est 404. Où est l'original?
[^ 3]: En fait, il semble que le fichier de clé privée contienne également les données de clé publique (?)
Lisez le fichier de clé publique créé en Python et essayez de chiffrer la phrase courte.
L'exemple est créé par l'application console (.NET Core 3.1).
main.cs
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
class Encrypt_sample
{
static void Main(string[] args)
{
const string message = @"This is test message!";
const string key_begin = "-----BEGIN PUBLIC KEY-----\r\n";
const string key_end = "\r\n-----END PUBLIC KEY-----";
string public_key = File.ReadAllText(@"public.pem");
public_key = public_key.Replace(key_begin, "").Replace(key_end, "");
var publicKeyBytes = Convert.FromBase64String(public_key);
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.ImportSubjectPublicKeyInfo(publicKeyBytes, out _);
byte[] encrypted = rsa.Encrypt(Encoding.UTF8.GetBytes(message), false);
File.WriteAllText(@"encrypted.txt", Convert.ToBase64String(encrypted));
}
}
}
Le message variable est la chaîne à chiffrer.
Après avoir lu le fichier de clé publique public.pem créé côté Python, il est converti en octets après suppression de l'en-tête et du pied de page, et lu dans la variable de type RSACryptoServiceProvider rsa avec ImportSubjectPublicKeyInfo (). [^ 4]
[^ 4]: Il existe une fonction appelée ImportRSAPublicKey (), mais c'est la bonne réponse.
Après cela, cryptez le message converti en une chaîne d'octets avec Encrypt () et enregistrez le texte converti en base64. La conversion est effectuée de manière à pouvoir être lu sous forme de fichier texte.
Si le deuxième argument de Encrypt () est défini sur false, le remplissage de PKCS # 1 v1.5 sera utilisé.
Dans la situation supposée, le chiffrement est effectué du côté C #, mais une fonction est créée afin de pouvoir confirmer que le chiffrement / déchiffrement peut également être effectué sur Python.
Encrypt.py
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
message = R"This is test message!"
def encrypt():
with open(file="public.pem", mode='rb') as file_read:
public_pem = file_read.read()
public_key = RSA.importKey(public_pem)
public_cipher = PKCS1_v1_5.new(key=public_key)
encrypted = public_cipher.encrypt(message=message.encode())
with open(file="encrypted.txt", mode='w', encoding='utf-8') as w:
w.write(base64.b64encode(encrypted).decode('utf-8'))
En tant qu'œuvre réelle,
est.
Le dernier est le décryptage.
Decrypt.py
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
def decrypt():
with open(file="private.pem", mode='rb') as file_read:
private_pem = file_read.read()
private_key = RSA.importKey(private_pem)
private_cipher = PKCS1_v1_5.new(key=private_key)
with open(file="encrypted.txt", mode='r', encoding='utf-8') as r:
encrypt_data = base64.b64decode(s=r.read())
decrypt_data = private_cipher.decrypt(ct=encrypt_data, sentinel="")
print(decrypt_data.decode('utf-8'))
Si la chaîne de caractères affichée par le dernier print () est la même que le message lors de sa création en C #, le déchiffrement réussit.
C'est une impression franche que je peux gérer avec un code plus court que ce à quoi je m'attendais. ** Je suis surpris de constater qu'il est relativement facile de chiffrer / déchiffrer dans plusieurs langues en ignorant les paramètres détaillés tels que la gestion des erreurs, la sécurité réelle et la force de chiffrement pratique.
Veuillez noter que le code ** est vraiment approprié et ne doit pas être mis en pratique. ** **
Q&A
--Q: Pourquoi n'y a-t-il pas de création et de décryptage de clé côté C #?
→ Décryptage mis à part (la clé privée est-elle déposée du côté client supposé?), Et la création de la clé a été une réussite car la sortie vers un format qui peut être partagé était un peu ennuyeuse. J'ajouterai s'il y a un bon moyen.
Recommended Posts