Cryptographie

Pour un projet j’ai dû faire un petit peu de cryptographie avec un échange de données via clés partagées.

On va générer une clé privée puis extraire la clé publique :

openssl genrsa -out private.pem 1024
openssl rsa -in private.pem -pubout -out public.pem

Le principe est d’écrire un message, le crypter avec la clé privée pour le décrypter avec la clé publique ou le crypter avec la clé publique pour le décrypter avec la clé privée.

En PHP, le code pourrait être le suivant

<?php
  $private = file_get_contents("private.pem");
  $public = file_get_contents("public.pem");

  // Encrypter avec la clé publique
  $content = "secret";
  openssl_public_encrypt($content, $crypted, $public, OPENSSL_PKCS1_OAEP_PADDING);
  echo base64_encode($crypted); // en base64 pour rendre la chose plus lisible

  // Décrypter avec la clé privée
  $crypted = base64_decode("base64-crypted-string");
  openssl_private_decrypt($crypted, $content, $private, OPENSSL_PKCS1_OAEP_PADDING);
  echo $content;

En python

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from requests import get
from base64 import b64encode

def encode(publickey, content):
  rsakey = RSA.importKey(publickey)
  rsakey = PKCS1_OAEP.new(rsakey)
  return b64encode(rsakey.encrypt(content))

def decode(privatekey, content):
  rsakey = RSA.importKey(privatekey)
  rsakey = PKCS1_OAEP.new(rsakey)
  return rsakey.decrypt(b64decode(content))

publickey = open("public.pem","r")
privatekey = open("private.prm","r")

plain_content = "secret"
crypted = encode(publickey, content)

plain_crypted = "base64-encrypted-string"
decrypted = decode(privatekey, crypted)

Note : ici on utilise la version PKCS1 v2 (OAEP) pour le padding et éviter quelques brêches du protocole.