Il est annoncé des le depart que ce
keygenme repose sur ElGamal donc :
ElGamal Signature ( version standard ) en quelques lignes:
Parametres:
- un nombre premier p,
- g et x aléatoires, inferieurs a p
- y = g^x mod p
clef publique = (y, g, p)
clef privée = x
Calcul de la signature de M:
Choix d ’un nombre aléatoire k ( k et p-1 premiers entre eux
)
r = g^k mod p
s = inv(k) * (M - x*r) mod (p-1)
Vérification de la signature (r,s):
v1 == v2 avec v1 = g^M mod p et v2 = y^r * r^s mod p
La solidité de cette signature repose sur le fait qu'il
est difficile de calculer des logarithmes discrets, c'est a dire que pour
des valeurs suffisament grande il est impossible, dans un temps raisonnable,
de determiner x grace à la relation: y = g^x mod p...
Analyse du code:
Recherche des GetDlgItemTextA ( api utilisé pour recuperer
les valeurs saisie )...
A partir de là, le code de la source n'etant pas protegé
il suffit d'observer ce qu'il se passe:
Complete le Nom avec des '*' ( 2Ah ) afin que celui comporte au
moins 1Eh caracteres:
_text:004010F8 PaddingName:
_text:004010F8
cmp esi, 1Eh
; cmp Longueur du nom, 1Eh
_text:004010FB
mov eax, esi
_text:004010FD
jge loc_0_401124
; si Longueur >= 1Eh
_text:004010FF
mov edx, 1Eh
; sinon
_text:00401104
lea edi, [ Name + esi] ; pointe a la fin
du nom
_text:0040110A
sub edx, esi
_text:0040110C
mov eax, 2A2A2A2Ah
_text:00401111
mov ecx, edx
_text:00401113
mov ebx, ecx
_text:00401115
shr ecx, 2
_text:00401118
repe stosd
; et copie des 2Ah
_text:0040111A
mov ecx, ebx
; afin que celui si comporte 1Eh caracteres
_text:0040111C
and ecx, 3
_text:0040111F
repe stosb
S'assure que les deux serials ne comportent que des caracteres permis:
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
_text:004011B1 Majuscule:
_text:004011B1
mov al, byte ptr [Serial1 + edx]
_text:004011B7
cmp al, 41h
_text:004011B9
jl short Minuscule
_text:004011BB
cmp al, 5Ah
_text:004011BD
jle short CheckFormatSerial
_text:004011BF
_text:004011BF Minuscule:
_text:004011BF
cmp al, 61h
_text:004011C1
jl short Nombre
_text:004011C3
cmp al, 7Ah
_text:004011C5
jle short CheckFormatSerial
_text:004011C7
_text:004011C7 Nombre:
_text:004011C7
cmp al, 30h
_text:004011C9
jl short ErreurSerial
_text:004011CB
cmp al, 39h
_text:004011CD
jg short ErreurSerial
_text:004011CF
_text:004011CF CheckFormatSerial:
_text:004011CF
_text:004011CF
mov edi, offset Serial
_text:004011D4
or ecx, 0FFFFFFFFh
_text:004011D7
xor eax, eax
_text:004011D9
inc edx
_text:004011DA
repne scasb
_text:004011DC
not ecx
_text:004011DE
dec ecx
_text:004011DF
cmp edx, ecx
_text:004011E1
jl short Majuscule
Ces quelques precautions prises le programme passe à la verification
Name\Serial1\Serial2: ( Si je reste assez evasif sur les methodes employées
pour l'analyse du code , c'est qu'elles sont tres rudimentaires:
intuition / logique / jeu avec les parametres d'entrés... )
Jusqu'a present le programme manipulait des chaines de caracteres donc
le programme va effectuer la convertion chaine de caractere => nombre au
format Miracl ( presence de la chaine 'MIRACL error from routine ' dans
le programme ;) )
_text:00401272
push offset Serial1
_text:00401277
push ebp
_text:00401278
call CvrtNumMiracl
_text:00401281
push offset Serial2
_text:00401286
push edx
_text:00401287
call CvrtNumMiracl
_text:00401290
mov ecx, [esp+64h+PadNameSize]
_text:00401294
push ebx
_text:00401295
push offset Name
_text:0040129A
push ecx
_text:0040129B
mov dword ptr [eax+238h], 10h
_text:004012A5
call CvrtStringMiracl
_text:004012AA
push offset aAc2db4fec8c62992db4f
_text:004012AF
push esi
_text:004012B0
call CvrtNumMiracl
Et là surprise, les valeurs renvoyées par les 2 premiers
call ne ressemblent pas vraiment a ce qui etaient attendus, c'est
d'autant plus etrange que quelques lignes plus bas tout semble fonctionner
correctement... Or la seule valeur ayant changée entre les differents
appels est celle se trouvant en [eax+238h], elle passe de 3Ch à
10h autrement dit de 60 à 16. "AC2DB4FEC8C62992DB4F" etant en base
16 on peut supposer que la valeur située en [eax+238h] est la base
utilisée lors de la convertion chaines => valeurs numeriques...
Autrement dif les serials sont interpretés comme si ils etaient
en base 60 ( ce qui est confirmé par le calcul ).
Par ordre croissant : "0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w
x" ( Alors pourquoi les caracteres y et z sont sont autorisés
? ;)) )
Au vu des parametres d'entrés on peut supposer que ce call va
effectuer un calcul... mais lequel ?
Le plus simple est de remplacer les differents parametres par des 0
ou des 1 et observer les effets que cela a sur la valeur resultat.
_text:004012B5
push ebx
; => NomR
_text:004012B6
push esi
; "AC2DB4FEC8C62992DB4F"
_text:004012B7
push 2
; 2
_text:004012B9
push ebx
; Nom
_text:004012BA
call CalculeNomR
CalculeNomR renvoit: NomR ( = Nom^2 mod AC2DB4FEC8C62992DB4F )
En utilisant la meme demarche ( l'analyse est simplifié
par le fait que l'on saut deja que l'on doit tomber sur du ElGamal)
_text:004012F3
push eax
; => Val1
_text:004012F4
push esi
; B54F430648C6B2A10FFB
_text:004012F5
push ebx
; NomR
_text:004012F6
push ecx
; 2E0C2DB4FEC8C6299A0C
_text:004012F7
call powMod
Val1 = 2E0C2DB4FEC8C6299A0C ^ NomR mod B54F430648C6B2A10FFB
_text:00401304
push edx
; => Val 2
_text:00401305
push esi
; B54F430648C6B2A10FFB
_text:00401306
push eax
; Serial2_
_text:00401307
push ebp
; Serial1_
_text:00401308
push ebp
; Serial1_
_text:00401309
push edi
; 4E0F2ACAD51C4CCDFB51
_text:0040130A
call sub_0_4034B0
val2 = 4E0F2ACAD51C4CCDFB51^Serial1_ * Serial1_^Serial2_ mod B54F430648C6B2A10FFB
_text:00401317
push ecx
_text:00401318
push edx
_text:00401319
call _compare
; compare val1 et val2
_text:0040131E
add esp, 38h
_text:00401321
test eax, eax
_text:00401323
push 0
_text:00401325
jnz short loc_0_401338
_text:00401327
mov eax, [esp+58h+hWnd]
_text:0040132B
push offset aGoood
; "GOOOD!!!"
_text:00401330
push offset aYourKeyIsGood_
Application de ElGamal:
On retrouve donc les equations permettant des verifier une "signature
ElGamal";
v1 = g^M mod p
v2 = y^r * r^s mod p
avec
g = 2E0C2DB4FEC8C6299A0C
M = NomR
p = B54F430648C6B2A10FFB
r = Serial1_
s = Serial2_
y = 4E0F2ACAD51C4CCDFB51
or
r = g^k mod p
s = inv(k) * (M - x*r) mod (p-1)
et
y = g^x mod p
c'est a dire
Serial1_ = 2E0C2DB4FEC8C6299A0C^k mod B54F430648C6B2A10FFB
Serial2_ = inv(k) * (NomR - x*Serial1_) mod (B54F430648C6B2A10FFB-1)
et
4E0F2ACAD51C4CCDFB51 = 2E0C2DB4FEC8C6299A0C^x mod B54F430648C6B2A10FFB
On retombe donc sur le probleme du logarithme discret mais heureusement
la taille a été limité afin que le temps de calcul
de ne soit pas trop long... ( cf les remerciments ;)))
Plusieurs solutions sont possibles pour effectuer ce calcul: utiliser
le programme index.c / index.cpp present dans le repertoire Source de Miracl,
utiliser celui de tE! (basé sur l'index.c de Miracl) ou taper les
mots "java+discrete logarithm" dans un moteur de recherche... :)
Discrete logarithm calculator
[ http://www.alpertron.com.ar/
]
The discrete logarithm problem is to find the exponent in the expression:
Base^Exponent = Power (mod Modulus).
This applet works only for prime moduli.
In this version of the discrete logarithm calculator only the Pohlig-Hellman
algorithm is implemented, so the execution time is proportional to the
square root of the largest prime factor of the modulus minus 1. The applet
works in a reasonable amount of time if this factor is less than 10^17.
|
Quelques minutes plus tard, on obtient:
x = 3F6536A02CD18F3B67D3
Calcul d'une clef valide:
Plus rien nous empeche alors de calculer des Serials corrects :
Nom |
Amenesia |
NomPad |
Amenesia********************** =
416D656E657369612A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A |
NomR |
3B240DEDDB1407B14B7 |
En prenant k = 1 ( pourquoi se compliquer la vie ;)):
Serial1 |
2E0C2DB4FEC8C6299A0C (en base 16) => 1drmL9dBJgRSLW (en base 60) |
Serial2 |
6AE06B269D5970281B3B (en base 16) => 3ppd7BUub4Qnax
(en base 60) |
Amusez vous bien...
Remerciements :
- jB meme si il s'est ouvertement moqué de moi... enfin il y
avait de quoi... ;)
Sans lui Maple serait encore entrain de tourner ;)) ( Maple a
des "petits" problemes avec les logarithme discret.... )
- Lise Grim pour sa patience et ce qu'elle nous fait decouvrire...
|