Chiffrement RSA
Cthiry
Messages postés
2
Statut
Membre
-
yg_be Messages postés 24281 Statut Contributeur -
yg_be Messages postés 24281 Statut Contributeur -
Bonjour,
je suis actuellement sur un projet de minitchat "sécurisé" et donc bien sûr j'ai besoin de la cryptographie RSA. J'ai donc réussi à générer des clés me semblant cohérentes sauf que le chiffrage ou le déchiffrage ne fonctionne pas certaines fois.
Par exemple, avec la clé publique (17,1333) et la clé privée (593,1333) c'est bon puisque le message déchiffré (à droite) est le même que le message d'origine (à gauche)

et d'autres fois, par exemple avec la clé publique (7,143) et la clé privée (103,143), le message décodé ne correspond pas au message d'origine

Voici mon code folklorique puisqu'il est en POO (ça me fait rire moi-même, à voir plus tard si je change ce délire occulte)
et aussi, j'ai recodé moi même les algorithmes l'aide du document https://jpq.pagesperso-orange.fr/divers/rsa/rsa.pdf
Configuration: Windows / Chrome 102.0.5005.61
je suis actuellement sur un projet de minitchat "sécurisé" et donc bien sûr j'ai besoin de la cryptographie RSA. J'ai donc réussi à générer des clés me semblant cohérentes sauf que le chiffrage ou le déchiffrage ne fonctionne pas certaines fois.
Par exemple, avec la clé publique (17,1333) et la clé privée (593,1333) c'est bon puisque le message déchiffré (à droite) est le même que le message d'origine (à gauche)

et d'autres fois, par exemple avec la clé publique (7,143) et la clé privée (103,143), le message décodé ne correspond pas au message d'origine

Voici mon code folklorique puisqu'il est en POO (ça me fait rire moi-même, à voir plus tard si je change ce délire occulte)
et aussi, j'ai recodé moi même les algorithmes l'aide du document https://jpq.pagesperso-orange.fr/divers/rsa/rsa.pdf
#chiffrement assymétrique
#si cela apparaît encore c'est que l'algorithme n'est pas fiable à 100% : certaines fois le cryptage décryptage fonctionne parfaitement et d'autres fois des erreurs se glissent... Peut-être des nombres trop gros ?
from random import randint
class Assymetrique:
"""classe représentant un système de chiffrement ASsymétrique
ATTRIBUTS :
- p : premier nombre premier à choisir (soi-m^me ou aléatoirement)
- q : deuxième nombre premier à choisir (soi-m^me ou aléatoirement)
- n : p*q
- M : (p-1)*(q-1)
- publique : clé publique (à faire passer au serveur pour qu'il chiffre la clé symétrique
-privee : clé privée (pour déchiffrer l'information venue du serveur)
+++++++++++++++
MÉTHODES :
- genere_cle_publique() : cherche 4 nombres e premiers et en séletionne un au hasard avec M et renvoie le tuple (e,n)
- genere_cle_privee() : cherche le premier entier d tel que d*e congru à 1 [M]
- chiffre(message) : chiffre le message passé en paramètre
- dechiffre(message) : déchiffre le message passé en paramètre
SOURCES pour la generation des clés :
https://jpq.pagesperso-orange.fr/divers/rsa/rsa.pdf
"""
def __init__(self,p=None,q=None):
"""constructeur de la classe Assymetrique,
prend en paramètre deux nombres premiers et génère les clés publique et privée asociée
ou si les entiers ne sont pas renseignés ou pas premiers, ils sont générés aléatoirement"""
if p==None or q==None or not(est_premier(p)) or not(est_premier(q)):
liste_premiers=nbr_premiers()
#print("les indices de la liste vont de 0 à ",len(liste_premiers)-1)
if p==None:
ind_p=randint(0,len(liste_premiers)-1)#on choisit aléatoirement l'indice du nombre p parmi les indices de la liste de nombre premiers
#print("indice de p= ",ind_p)
p=liste_premiers[ind_p]
liste_premiers.remove(p)#on enlève p pour éviter de le rechoisir
if q==None:
if p in liste_premiers:
liste_premiers.remove(p)#on enlève p de la liste mais on verifie qu'il y est sinon erreur
ind_q=randint(0,len(liste_premiers)-1)#on choisit aléatoirement l'indice du nombre q parmi les indices de la liste de nombre premiers
#print("indice de q= ",ind_q)
q=liste_premiers[ind_q]
#on affecte les valeurs dont on a besoin pour calculer les clés aux attributs p, q, n, M
self.p=p
self.q=q
#print(f"p={p} et q ={q}")
self.n=self.p*self.q
self.M=(self.p-1)*(self.q-1)
#on genere les clés
self.publique=self.genere_cle_publique()
#print("cle_publique ok")
self.privee=self.genere_cle_privee()
#print("cle privee ok")
def genere_cle_publique(self):
e=1#e ne peut être qu'impair
j=e+2#on essaie donc tous les nombres impairs de 3 à M exclu
b=True # et on s'arrête au 3ème e trouvé mais on pourrait continuer
i=0
e_possibles=[]
while b and j<self.M:
#print("j= ",j)
i1=self.M#on applique l'algorithme d'euclide à (p-1)(q-1) et j
j1=j
k=i1%j1
while k>1:
k=i1%j1
i1=j1
j1=k
#print("k= ",k)
if k==0:
j+=2#k=0 ça ne va pas
else:
i+=1
e_possibles.append(j)
j=j+2
#print(e_possibles)
if i==4:
b=False
if b:
print("pas de e dans l'intervalle [3;M[")
else:
#print(e_possibles)
e=e_possibles[randint(0,len(e_possibles)-1)]
return (int(e),self.n)
def genere_cle_privee(self):
"""recherche le premier entier d =k*M+1 divisible par e"""
i=1
e=self.publique[0]
while i%e!=0:
i=i+self.M
d=i/e
return (int(d),self.n)
def chiffre(self,message):
"""prend un message en paramètre et le retourne chiffré"""
#print("+++++on chiffre+++++")
e=self.publique[0]
n=self.n
message_code=""
for lettre in message:
code_lettre=(ord(lettre)**e)%n
#print(f"{ord(lettre)}->{code_lettre}")
message_code+=chr(int(code_lettre))
return message_code
def dechiffre(self,message_code):
"""prend un message chiffré en paramètre et le retorne déchiffré"""
#print("+++++on déchiffre+++++")
d=self.privee[0]
n=self.n
message_en_clair=""
for lettre in message_code:
decode_lettre=(ord(lettre)**d)%n
#print(f"{ord(lettre)}->{decode_lettre}")
message_en_clair+=chr(decode_lettre)
return message_en_clair
def nbr_premiers(n=50):
"""prend en paramètre un nombre entier n et retourne la liste des nombres_premiers infèrieurs à n
ici n est utilisé avec la valeur 50 car sur l'ordinateur de test, une liste avec plus d'entiers premiers ammène à des valeurs trop autes dans les calculs ce qui renvoie une erreur"""
l=[2,3,5,7,11]
for i in range(13,n,2):#2on avance de 2 en 2 car les nombres premiers sont tous impairs
if est_premier(i):
l.append(i)
return l
def est_premier(n):
"""vérifie si le nombre entier passé en paramètre est premier, True si oui False sinon"""
for i in range(2,n):
if n%i==0:
return False
return True
if __name__=='__main__':
chiffrement=Assymetrique()
print(chiffrement.publique)
print(chiffrement.privee)
messages=["bonjour le monde","moi je vais très bien","EEEEETTTTT toi ?","ééééé"]
for message in messages:
code=chiffrement.chiffre(message)
decode=chiffrement.dechiffre(code)
assert(len(message)==len(code)and len(message)==len(decode))
print(message,decode)
#assert message==decode
Configuration: Windows / Chrome 102.0.5005.61
2 réponses
bonjour,
je pense que tu as un souci quand tu utilises des nombres premiers trop petits.
je pense que tu as un souci quand tu utilises des nombres premiers trop petits.
Cthiry
Messages postés
2
Statut
Membre
Merci pour la réponse, en orientant mes recherches vers cette idée, j'ai vu que si p et q sont choisis tels que n=p*q <255 alors le chiffrement n'est pas bijectif.
yg_be
Messages postés
24281
Statut
Contributeur
1 584
>
Cthiry
Messages postés
2
Statut
Membre
Ce qui explique que je n'avais plus de soucis en prenant des nombres premiers >=17.