Communication de données chiffrées entre Python et C #

Communication de données chiffrées entre Python et C

introduction

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. ** **

Situation présumée

  1. Créez une clé RSA côté serveur (Python)
  2. Le côté client (C #) a une clé publique créée, qui crypte le fichier texte.
  3. Décryptez le fichier crypté envoyé (décidé) côté serveur avec la clé privée

environnement

Côté Python

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

Côté C

.NET Core 3.0 ou supérieur (.NET Framework 5.0 RC1) est requis pour que certaines fonctions appliquent .NET Standard 2.1.

la mise en oeuvre

Créer une clé publique / privée

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 (?)

Chiffrement (C #)

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é.

Chiffrement (Python)

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,

  1. Importez le fichier de clé publique (public_key)
  2. Conversion du format public_key au format PKCS1_v1_5 (?) (?) (Public_cipher)
  3. Crypter le message en utilisant public_cipher

est.

Décryptage (Python)

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'))
  1. Importer le fichier de clé privée (private_key)
  2. Conversion du format clé_privée au format PKCS1_v1_5 (?) (?) (Chiffre_privé)
  3. Décryptez le contenu du fichier chiffré à l'aide de private_cipher

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.

Impressions

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. ** **

Choses que vous devriez ajouter

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

Communication de données chiffrées entre Python et C #
[Python] Mémo de conversion entre les données temporelles et les données numériques
Échangez facilement des données entre Python, R et Julia à l'aide du format Feather
Étudiez l'échange de données Java et Python avec Apache Arrow
Frontière entre C et Golang
Différence entre Ruby et Python Split
Différence entre list () et [] en Python
Différence entre == et est en python
Coopération entre le module python et l'API
Différence entre Python, stftime et strptime
Différence entre la série python2 et la série python3 dict.keys ()
Hashing de données en R et Python
[Python] Différence entre fonction et méthode
Python - Différence entre exec et eval
[Python] Différence entre randrange () et randint ()
[Python] Différence entre trié et trié (Colaboratoire)
Communiquez entre Elixir et Python avec gRPC
Différence d'authenticité entre Python et JavaScript
Différences entre Ruby et Python dans la portée
différence entre les instructions (instructions) et les expressions (expressions) en Python
Implémenter le filtre FIR en langage Python et C
Différences entre la syntaxe Python et Java
Différences dans la relation entre PHP et Python enfin et quitter
Différence entre @classmethod et @staticmethod en Python
Structure de données Python et implémentation interne ~ Liste ~
Différence entre append et + = dans la liste Python
Différence entre non local et global en Python
Ecrire le fichier O_SYNC en C et Python
[Python] Différence entre la méthode de classe et la méthode statique
Structure et fonctionnement des données Python (mémo d'apprentissage Python ③)
Représentez facilement des données graphiques dans le shell et Python
[Python3] Basculer entre Shift_JIS, UTF-8 et ASCII
Communication socket par langage C et Python
[python] Différence entre la sortie rand et randn
Compressez les données python et écrivez sur sqlite
Différences de multithreading entre Python et Jython
Différence entre Ruby et Python (syntaxe de base)
RaspberryPi L Chika avec Python et C #
Correspondance entre les fonctions intégrées de Python et Rust
Modèle d'extension Python C / C ++ - Passez des données à Python en tant que np.array
Relation entre la conversion des types de données Firestore et Go
Comment générer une séquence en Python et C ++
Analyse de données python
Recevoir et afficher les données de formulaire HTML en Python
La réponse de "1/2" est différente entre python2 et 3
[Python] Permutation des lignes et des colonnes de données Numpy
[python] Différence entre variable et self. Variable dans la classe
[Python] Comment lire les données de CIFAR-10 et CIFAR-100
À propos de la différence entre "==" et "is" en python
Jeu manuel Python (interopérabilité entre CSV et PostgreSQL)
notes de python C ++
Essayez d'importer des données MLB sur Mac et Python
fonctions cv2 et types de données (liaison python OpenCV)
Différences de comportement entre les opérateurs append () et "+ =" lors de l'ajout de données à une liste en Python
Traitement pleine largeur et demi-largeur des données CSV en Python
Liste des bibliothèques Python pour les data scientists et les data ingénieurs
Benchmarks langage C, Java, Python avec factorisation prime
Expérience de comparaison de la vitesse d'écriture de fichier entre python 2.7.9 et pypy 2.5.0
Reçoit et génère la sortie standard des implémentations Python 2 et Python 3> C
[Ruby vs Python] Comparaison de référence entre Rails et Flask