Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save YannBouyeron/f39893644f89dd676297cc3bc67eaedb to your computer and use it in GitHub Desktop.
Save YannBouyeron/f39893644f89dd676297cc3bc67eaedb to your computer and use it in GitHub Desktop.
Le chiffrement RSA avec le module PyCrypto.

Le chiffrement RSA avec le module PyCrypto.

Le chiffrement RSA est un chiffrement asymétrique.

Le principe du chiffrement asymétrique

Oumar voudrait pouvoir correspondre secrètement avec Aminata , sans que Sarah ne puisse lire les messages que Aminata lui envoie. Oumar génère un jeu de deux clés de chiffrement:

  • une clé publique , qu'il envoie à Aminata, et qui permettra à Aminata de chiffrer les messages qu'elle enverra à Oumar
  • une clé privée, qu'il conserve précieusement pour lui, et qui lui permettra de déchiffrer les messages chiffrés par Aminata avec sa clé publique.

Oumar peut distribuer la clé publique à autant de personne qu'il le souhaite, cette clé ne sert qu'à chiffrer les messages ! Si Oumar veut pouvoir chiffrer les messages qu'il envoie à Aminata, il faut que Aminata génère un autre jeu de clés, et qu'elle lui donne sa clé publique.

Installer le module Crypto

Sous Debian

sudo apt-get install python-crypto 

Ou , si vous êtes sous Python 3:

sudo apt-get install python3-crypto

Avec pip

pip install crypto

Ou :

pip3 install crypto

Importer crypto

Nous avons besoin que de la classe RSA du module PublicKey

from Crypto.PublicKey import RSA

Fabriquer un couple de clés.

key = RSA.generate(1024)

Key est un objet de la classe RSA:

>>> key
<_RSAobj @0x108b6a9e8 n(1024),e,d,p,q,u,private>

Il contient la clé privée.

La clé publique est contenue dans l'objet key.publickey()

>>> key.publickey()
<_RSAobj @0x108b385f8 n(1024),e>

Exporter une clé

Il est possible d'afficher le contenu d'un clé:

k = key.exportKey('PEM')

p = key.publickey().exportKey('PEM')

>>> k
b'-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQCo0uSjLaBXkFtA3qOcrxCvSvQayM2AirDNY6JvTWEHGbn7qRey\nNL+XOY1jH9UjTORzdcIIHRtjNGBs6DKOldON8wSM1YhikGX6lqEq6S0nOy7oAFYF\nYV4xCtcMEascmXcThtMp/iHLYtE8UWYcKOG68pLLqwRJuCqKMWEiJ/P0/QIDAQAB\nAoGAczL1MSQBNb8bhbhmjJQpHnRW/a/oCr6Yxo4mWSzD+MRlVISd1syHr/llsS4X\nkm71tJO2QzMZbShgY/BOD13NbQNO5MJ/nB6P1lPXIGoxc9xthYhyXpCNqUmKp7JU\nSAHb7IVkHZpoHb/wxJiZgxPw2MG091ERAqAeAwQCjFCZ+AECQQDGWf8KhzY9JU59\n8ngnYTOEfhH0c9vLmAcwTZ1bwNQXDmrUg8GQARf1RVywVsAgheQi6V4CdskwpjYa\n2gh2yO8dAkEA2ePvmvw8Ll04k+NuVIQ/GyjPglvBs+3zIcXgTVcJF652IVDyprLt\nRJz5reTLPXWv3rIrZxu5N+txej1d6QDXYQJAH/2f3sjT/KSptjKHIoLQ1kunBbAy\nAPIyJp4+BPBixJ00qbXeYCVtAcgAHQjAz/4IP4E4Alm6NTh5fXcw6keaGQJBAKID\nI/QfvTfURO9h2nWpZ6rwK2uIgn0hXvkrwt5+6tna9SdMo0BkJpwwBE7SonRuf3id\nDjy6lnwH6vazjpJj98ECQQDDYJbZW1lQTA1VgNv5vUzg+mbFsDABgKsXVsxXWI45\nzoZSQ2w7CVapgzN72z6wZ+ICw5ITDg5PSsoKd+SBUnaF\n-----END RSA PRIVATE KEY-----'
>>> 
>>> 
>>> p
b'-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo0uSjLaBXkFtA3qOcrxCvSvQa\nyM2AirDNY6JvTWEHGbn7qReyNL+XOY1jH9UjTORzdcIIHRtjNGBs6DKOldON8wSM\n1YhikGX6lqEq6S0nOy7oAFYFYV4xCtcMEascmXcThtMp/iHLYtE8UWYcKOG68pLL\nqwRJuCqKMWEiJ/P0/QIDAQAB\n-----END PUBLIC KEY-----'

Sauvegarder ses clés dans des fichiers

Avec Python 3

with open('private.pem','w') as kf:
	kf.write(k.decode())
	kf.close()

with open('public.pem','w') as pf:
	pf.write(p.decode())
	pf.close()

Avec Python 2.7

with open('private.pem','w') as kf:
	kf.write(k)
	kf.close()

with open('public.pem','w') as pf:
	pf.write(p)
	pf.close()

Importer des clés à partir d'un fichier

with open('private.pem','r') as fk:
	priv = fk.read()
	fk.close()

with open('public.pem','r') as fp:
	pub = fp.read()
	fp.close()

privat = RSA.importKey(priv)
public = RSA.importKey(pub)

On peut vérifier que les clés importées sont bien indentiques aux originales:

>>> privat == key
True
>>> public == key.publickey()
True

Chiffrer

public_key = key.publickey()
enc_data = public_key.encrypt(b"""bonjour c'est un message secret""", 32)

On appelle enc_data dans le Shell :

>>> enc_data
(b'\x0bL\x1e\xf6\xac?\xb2\x8c>//\xc5\xbe\xe4k\x9d\x99b\x9e\xbc_\xfb\n\x9fJ\'\xe8\x8e|\x88\xb4\x9a\xcf\xb1K\xdb\x04HE\'\xe5Q\x86p\xe3E\xcbG\x98R"b\xad\x18A\x99\x1e;y\xc0\xee\xc8\xeaZ\x02s\xe3\xacM3\xd3\x02g\xd8\x11\xc2\xe9\xed\xf7[pQa\xbd\xdd\x0bb\x131\xf8\xde\xb5\xea\xa8\x08\t\xf87\xa9\xefX\xf0\xf7\x077\xad<\x13\xaa\xf9\xdb\x11*b\xbd\xfa#\x83\x8a@\xc0\x98\xf0\x9d\x16\xdb\xdbL',)

Dechiffrer

x = key.decrypt(enc_data)
x = x.decode('utf-8')

On appelle x dans le Shell:

>>> x
"bonjour c'est un message secret"

Le code complet

from Crypto.PublicKey import RSA


#creation d´un couple de clés
key = RSA.generate(1024)

#chiffrage
public_key = key.publickey()
enc_data = public_key.encrypt(b"""bonjour c'est un message secret""", 32)

#dechiffrage
x = key.decrypt(enc_data)
x = x.decode('utf-8')

#afficher ses clés:
k = key.exportKey('PEM')
p = key.publickey().exportKey('PEM')

#sauvegarder ses clés dans des fichiers:
with open('private.pem','w') as kf:
	kf.write(k.decode())
	kf.close()

with open('public.pem','w') as pf:
	pf.write(p.decode())
	pf.close()

#importer des clés à partir d'un fichier
with open('private.pem','r') as fk:
	priv = fk.read()
	fk.close()

with open('public.pem','r') as fp:
	pub = fp.read()
	fp.close()

privat = RSA.importKey(priv)
public = RSA.importKey(pub)
from Crypto.PublicKey import RSA
#creation d´un couple de clés
key = RSA.generate(1024)
#chiffrage
public_key = key.publickey()
enc_data = public_key.encrypt(b"""bonjour c'est un message secret""", 32)
#dechiffrage
x = key.decrypt(enc_data)
x = x.decode('utf-8')
#afficher ses clés:
k = key.exportKey('PEM')
p = key.publickey().exportKey('PEM')
#sauvegarder ses clés dans des fichiers:
with open('private.pem','w') as kf:
kf.write(k.decode())
kf.close()
with open('public.pem','w') as pf:
pf.write(p.decode())
pf.close()
#importer des clés à partir d'un fichier
with open('private.pem','r') as fk:
priv = fk.read()
fk.close()
with open('public.pem','r') as fp:
pub = fp.read()
fp.close()
privat = RSA.importKey(priv)
public = RSA.importKey(pub)
@patastronch
Copy link

@backl1n
Copy link

backl1n commented Dec 11, 2020

how for read file in place string message @YannBouyeron

@ipolo0000i
Copy link

read about encrypt fonction on : https://www.dlitz.net/software/pycrypto/api/current/
"Attention: this function performs the plain, primitive RSA encryption (textbook). In real applications, you always need to use proper cryptographic padding, and you should not directly encrypt data with this method. Failure to do so may lead to security vulnerabilities. It is recommended to use modules Crypto.Cipher.PKCS1_OAEP or Crypto.Cipher.PKCS1_v1_5 instead. "

@Zakod
Copy link

Zakod commented Oct 1, 2022

Merci pour votre article. J'essaye votre code, j'ai installé crypto avec pip, je n'arrive pas à importer RSA. Même en espectant la minuscule de crypto, ça donne ça : donne ça : No module named 'crypto.PublicKey'. J'ai essayé avec une minuscule à publicKey, mais non. J'ai aussi essayé d'importer tout, mais pas de RSA.

@backl1n
Copy link

backl1n commented Oct 1, 2022

@Zakod why you ping me

@Zakod
Copy link

Zakod commented Oct 1, 2022

I dont understand ! I was talking to the author, not to you.

@YannBouyeron
Copy link
Author

Bonjour,

La bibliothèque python-crypto est probablement dépréciée…

Utilisez pycryptodome à la place : https://gist.github.com/YannBouyeron/c5367809904a682767669b6a51f03aa3

@Zakod
Copy link

Zakod commented Oct 1, 2022

Merci, je vais étudier ça. J'ai aussi trouvé un post qui parle du module rsa. Je suis revenu aujourd'hui vers le chiffrage asymétrique, sur le conseil d'un collègue qui répondait à cette demande : pour envoyer des mails automatiques, il faut communiquer un mot de passe d'authentification à la fonction qui envoie le mail. Si le code est déposé, chez Github par exemple, il faut garder ce mot de passe secret. Le stocker dans un fichier ou une BDD. Mais celle-ci peut-être violée. Il faut donc crypter. Mais comment fait le module de cryptage, public lui aussi, pour garder ses secrets. Alors le collègue me dit qu'une solution est le chiffrage asymétrique. Mais il me semble que le problème se transpose juste sur la clé privée.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment