DÉCRYPTER LES FICHIERS IMAGE JPG (VOUS AVEZ ÉGARÉ LA CLÉ)

cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 - 24 oct. 2003 à 00:06
mokermi Messages postés 1 Date d'inscription mardi 13 février 2007 Statut Membre Dernière intervention 12 mars 2010 - 12 mars 2010 à 16:20
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/17322-decrypter-les-fichiers-image-jpg-vous-avez-egare-la-cle

mokermi Messages postés 1 Date d'inscription mardi 13 février 2007 Statut Membre Dernière intervention 12 mars 2010
12 mars 2010 à 16:20
Salut moi ce serai pour decrypter les photos de la naissance de mon fils que j'ai encrypté avec windows xp pro et depuis mon passage sur vista impossible de les lire et je n'ai ni l'ancienne version de xp ni rien d'autres ...je ne sais plus comment faire en plus ma femme me met la pression aidez moi SVP !!!!
Est ce possible de les decrypter ???
Merci d'avance a tous !!!
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
24 août 2006 à 00:20
Vraiment très intéressant.
Je testerai à fond... plus tard... fatigué...

Ben, euh... fais de beaux rêves, Cirec ^^
Utilisateur anonyme
23 août 2006 à 23:57
Voilà
cette procedure est vraiment la plus rapide de toutes :

procedure DecodeMemoryStreamBlock(const FromFileName, ToFileName: string);
var
Key,
PosPointer: LongWord;
Buffer : Array[1..1024] of Byte;
MStream: TMemoryStream;
NbALire, NbLu, TotalLu : LongInt;
i: Integer;
begin
MStream := TMemoryStream.Create;
try
MStream.LoadFromFile(FromFileName);
MStream.Seek(0, soFromBeginning);
MStream.Read(Key, 4);
Key := Key xor $E0FFD8FF;
MStream.Seek(0, soFromBeginning);
TotalLu := 0;
NbALire := SizeOf(Buffer);
Repeat
If (TotalLu + NbALire) > MStream.Size Then NbALire := MStream.Size - TotalLu;
PosPointer := MStream.Position;
NbLu := MStream.Read(Buffer, NbALire);
For I:= 1 to NbLu do
Buffer[I] := Buffer[I] Xor Key;
MStream.Position := PosPointer;
MStream.WriteBuffer(Buffer, NbLu);
TotalLu := TotalLu + NbLu;
Until TotalLu >= MStream.Size;
MStream.SaveToFile(ToFileName);
finally
MStream.Free;
end;
end;


Bonne nuit ;-)
@+
Cirec
Utilisateur anonyme
23 août 2006 à 22:35
Ce qui est bizarre c'est que DecodeMemoryStream est plus lent
que la mienne ???

je vais essayer un mix des deux ...
@+
Cirec
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
23 août 2006 à 16:39
Salut Cirec,

J'ai repris ce code car il était vraiment mal foutu et me faisait honte. Son seul intérêt est de montrer le mécanisme du cryptage par xor.

Quant au problème de la rapidité, il est résolu dans un code posté ultérieurement, grâce à Shining et à TMemoryStream.

Mais ta manière de procéder m'intéresse, elle est en quelque sorte à mi chemin entre BlockRead et FileStream, et je vais l'étudier de plus près.

Sinon, j'en ai deux autres en réserve, il va falloir que je compare les performances...

Une version assez rapide :

procedure DecodeFileBlocks(const FromFileName, ToFileName: string);
var
OldF, NewF: file;
Buffer: array[0..1023] of Byte;
FilePointer: LongInt; // pointeur de position dans le fichier
BytesRead: Integer;
i: Integer;
Key: Byte;
begin
AssignFile(OldF, FromFileName);
try
Reset(OldF, 1);
BlockRead(OldF, Buffer, SizeOf(Buffer), BytesRead);
Key := Buffer[0] xor 255;
Seek(OldF, 0);
AssignFile(NewF, ToFileName);
try
Rewrite(NewF, 1);
while not Eof(OldF) do
begin
FilePointer := FilePos(OldF);
BlockRead(OldF, Buffer, SizeOf(Buffer), BytesRead);
for i := 0 to BytesRead - 1 do
Buffer[i] := Buffer[i] xor Key;
Seek(NewF, FilePointer);
BlockWrite(NewF, Buffer, BytesRead);
end;
finally
CloseFile(NewF);
end;
finally
CloseFile(OldF);
end;
end;

Une version ultra rapide :

procedure DecodeMemoryStream(const FromFileName, ToFileName: string);
var
Tmp,
Key,
PosPointer: LongWord;
MStream: TMemoryStream;
begin
MStream := TMemoryStream.Create;
try
MStream.LoadFromFile(FromFileName);
MStream.Seek(0, soFromBeginning);
MStream.Read(Tmp, 4);
Key := Tmp xor $E0FFD8FF;
MStream.Seek(0, soFromBeginning);
while MStream.Position < MStream.Size do
begin
PosPointer := MStream.Position;
MStream.Read(Tmp, 4);
Tmp := Tmp xor Key;
MStream.Position := PosPointer;
MStream.Write(Tmp, 4);
MStream.Position := PosPointer + 4;
end;
MStream.SaveToFile(ToFileName);
finally
MStream.Free;
end;
end;

Quoi qu'il en soit, voilà un beau catalogue des manières de lire et écrire dans les fichier, c'est presque un tutoriel, lol...

A +
japee
Utilisateur anonyme
23 août 2006 à 15:57
Salut,

j'ai fait un teste (eh oui j'ai aussi des images cryptées ;-))

et ma procedure est ~ 10 fois plus rapide que DecodeFileStream et ~ 15 fois plus que DecodeFile :

{ Avec TFileSteam Bloc par Bloc}

procedure DecodeFileStreamBlock(const FromFileName, ToFileName: string);
var
FSCod, FSDeCod: TFileStream;
Key: Byte;
Buffer : Array[1..1024] of Byte;
NbALire, NbLu, TotalLu : LongInt;
i: Integer;
begin
FSCod := TFileStream.Create(FromFileName, fmOpenRead);
FSDeCod := TFileStream.Create(ToFileName, fmCreate);
try
FSCod.Read(Key, 1);
Key := Key xor 255; // calcul de la clé de cryptage
(*
{ TStream seek origins }
soFromBeginning = 0;
soFromCurrent = 1;
soFromEnd = 2;
*)
FSCod.Seek(0, SoFromBeginning);
// Initialisation des Variables
TotalLu := 0;
NbALire := SizeOf(Buffer);
Repeat // boucle qui lis par bloc de 1024 mais pas plus que la taille initiale du fichier d'origine
If (TotalLu + NbALire) > FSCod.Size Then NbALire := FSCod.Size - TotalLu;
NbLu := FSCod.Read(Buffer, NbALire);
For I:= 1 to NbLu do
Buffer[I] := Buffer[I] Xor Key;
FSDeCod.WriteBuffer(Buffer, NbLu); // on écris dans le fichier de sortie par Bloc
TotalLu := TotalLu + NbLu; // on fait les comptes
Until TotalLu >= FSCod.Size;
finally
FSDeCod.Free;
FSCod.Free;
end;
end;

Japee, pour répondre à ton problème de lecture, il faut changer le FileMode :

Var OldFileMode : Integer;
begin
OldFileMode:= FileMode;// On memorise le FileMode afin de le restituer à la fin
FileMode := fmOpenRead; // On le change en Lecture Seul
AssignFile(FCod, FromFileName);
// ... traitement
FileMode := OldFileMode; // On restitue le FileMode

Pour les Stream c'est normal que le problème soit résolut puisque tu ouvres le fichier directement avec le bon paramètre :
FSCod := TFileStream.Create(FromFileName, fmOpenRead);

Voilà c'est tout
Bon testes ;-)
@+
Cirec
Fulminex Messages postés 1 Date d'inscription jeudi 11 août 2005 Statut Membre Dernière intervention 11 août 2005
11 août 2005 à 02:43
J'ai écrit ce code en Turbo Pacal à l'époque... Si ton code est lent, c'est parce-qu'il lit octet par octet... Une lecture par bloc et un traitement séparé du bloc en mémoire, ça accélère "achment"! ^^
kimmelf2 Messages postés 267 Date d'inscription lundi 22 septembre 2003 Statut Membre Dernière intervention 27 novembre 2005
16 mai 2004 à 22:54
ca n'aurais pas ete plus simple de donner les codes hexa ???? :-)
deep69 Messages postés 1 Date d'inscription vendredi 26 mars 2004 Statut Membre Dernière intervention 16 mai 2004
16 mai 2004 à 13:48
Salut,

yep excelent avec filestream,hélas j'ai le PCMag n°147 et

l'image ne ce decrypte pas :-(

voici les 4 premiers octets que j'obtient ÿåóö au lieu de ÿØÿà
cs_darkstorm Messages postés 44 Date d'inscription dimanche 3 février 2002 Statut Membre Dernière intervention 22 mai 2006
3 nov. 2003 à 23:59
Merci de la précision, en gros un xor avec une clé de 1 caractère ils se sont pas trop foulés mais d'un côté il faut déjà avoir l'idée de comparer le fichier avec un modèle et de tomber sur la SEULE fonction symétrique :-), bravo à toi et bon travail !

Vito
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
3 nov. 2003 à 15:16
Oui, darkstorm, on se sert du premier byte pour déterminer la clé, car on sait que le premier byte d'un fichier jpg "normal" (non crypté) est "FF" (facile à voir avec un éditeur hexadécimal), et 5A pour un fichier crypté.
On peut supposer que l'opérateur logique xor est utilisé, coup de bol, c'est le cas !
En partant du principe que ByteCodé xor ByteDécodé Clé, et que ByteCodé xor Clé ByteDécodé, reste plus qu'à appliquer...
Comme ils se sont pas foulés, en calculant la clé sur le premier octet et en l'appliquant à tous les bytes du fichier (y compris le premier bien sûr), on obtient le fichier décrypté.
On pourrait se dispenser de chercher la clé à chaque fois, car il semblerait que ce soit toujours la même, donc ça ferait gagner un peu de temps...
Bon, mais s'il leur venait à l'idée de changer la clé, hein ?
Ou alors ne calculer qu'une seule fois, sur un fichier, en partant du principe que la même clé sera utilisée pour toute la série d'image cryptées...
Tout est envisageable, il ne s'agit ici que du principe, à chacun de voir pour améliorer la rapidité, il semble qu'il y ait des possibilités ! ;)
cs_darkstorm Messages postés 44 Date d'inscription dimanche 3 février 2002 Statut Membre Dernière intervention 22 mai 2006
2 nov. 2003 à 00:33
Salut,

En gros si j'ai bien compris, leur cryptage bidon qu'on inverse le premier byte du fichier (ben oui si on xor 255 c'est équivalent à un not()), ce qui nous donne la clé, ensuite on l'utilise pour décrypter le reste du fichier... mais est-ce que la clé est utilisée pour décrypter le 1er byte ou on le laisse tel quel?
jbanety Messages postés 30 Date d'inscription mardi 24 décembre 2002 Statut Membre Dernière intervention 30 juin 2011
30 oct. 2003 à 08:23
ça me rappelle quand j'avais trouvé une source pour décoder la clé de cryptage des cd DCOD, les petit cd's de cul pour les cochons :)

Enfin bon j'ai essayé et excellent boulot !
kimmelf2 Messages postés 267 Date d'inscription lundi 22 septembre 2003 Statut Membre Dernière intervention 27 novembre 2005
29 oct. 2003 à 01:00
nan je vais plutot installer palladium !

NAANNNNNN PAS TAPER !!!!!!!!

j'rigole

je me tate entre un bon vieux 2000 et XP. perso j'aime pas le nouveau style de XP. parais qu'on peux choisir d'avoir un style d'interface classique, mais j'estime que 2 interfaces dont 1 que j'aime pas = gaspillage de place sur le DD

et puis en plus simple, j'ai pas les moyens de payer un XP pour l'essayer et voire si j'aime
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
28 oct. 2003 à 17:42
Merci pour tes explications, kimmelf, les problèmes d'accès aux fichiers sous Windows sont effectivement communs à tous les langages, et je n'ai en principe pas de difficulté à en comprendre la logique ;)
Ce qui est difficilement compréhensible, c'est qu'un fichier en lecture seule est (apparemment ?) impossible à lire (j'ai bien dit à lire), du moins byte par byte, s'il est situé sur le disque dur ???
C'est du moins le cas ici en lisant le fichier (byte par byte), en modifiant ce byte, et en copiant le byte obtenu dans un fichier cible.
Alors que cela ne pose pas de problème (et là on retrouve la logique) s'il est lu à partir d'un support CD-Rom...
Mais bon, le problème ne se pose plus si l'on utilise TFileStream (conseillé !), alors... (d'autant plus que c'est 2 fois plus rapide).
Bon courage avec ta réinstallation, paraît que XP plante moins, mais on aime ou pas... et puis c'est dur de suivre l'évolution, on n'a pas forcément les moyens financiers de changer de système d'exploitation tous les 2 ans !
Il faudrait avoir le courage de migrer vers Linux ! ;)
Enfin, en réinstallant Win98 SE tous les ans, j'arrive à ne pas trop galérer :(
Bon courage, à + (et reviens vite à Delphi !) ;)
kimmelf2 Messages postés 267 Date d'inscription lundi 22 septembre 2003 Statut Membre Dernière intervention 27 novembre 2005
27 oct. 2003 à 23:08
japee>
ben si tu coche "lecture seule", c'est que tu veux pas que le fichier soit modifie, donc windows et les IDEs, dans leurs extreme generosite, bloque l'acces a ce type de fichier lorsqu'il y a un risque d'ecriture.

par ex, en C, les 3 lignes suivantes (et derivees) ne sont pas autorisees a acceder a un fic en lecture seule car le mode d'acces laisse suppose que le prog peu avoir besoin d'ecrire dans le fichier:
f = fopen("nom_du_fichier.ext" , "rw")
f = fopen("nom_du_fichier.ext" , "w")
f = fopen("nom_du_fichier.ext" , "a")

alors que la ligne suivante est acceptee car "r" signifie un acces au fichier en n'ayant besoin que de la lecture donc ca ne pose pas de probleme ....
f = fopen("nom_du_fichier.ext" , "r")



japee>
Ben le bravo, c'est + pour le fait que tu ai adapte le pgm original que pour son exec car .... j'ai plus delphi (formattage en prevision, donc nettoyage pour mieux retrouver ce que je doit graver avant de "debugguer" windows (ben oui, qd windows bug, pour corriger, on format non ???)) donc j'ai pas pu essayer ! mais je me ralie au autre posteurs : si ils disent que ca marche, c'est que ca marche ...

j'adore les operations logiques moi ... :-D :-D :-D
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
27 oct. 2003 à 16:45
Bravo, lenine! Exactement ce qu'il fallait faire en attendant que j'aie pondu un exécutable mettant ce code en oeuvre... pffff, j'arrive pas à me motiver, mais ça va me prendre d'un coup, c'est sûr.

Quand je vous dit que ça marche, hein ?

Surtout en utilisant la procedure avec TFileStream, qui élimine les problèmes de fichier en lecture seule copiés sur le disque dur (j'ai jamais trop bien compris pourquoi ça posait problème...)
cs_lenine Messages postés 1 Date d'inscription lundi 25 août 2003 Statut Membre Dernière intervention 27 octobre 2003
27 oct. 2003 à 10:11
Je suis débutant dans la prog aussi, j'ai couplé ton code avec un autre code présant sur le site qui recherchait des fichiers sur le disque dur, et ton programme a quasiment tout décrypté, j'en reviens pas! c'est fantastique, on a souvent des jpg livrés sur des cds qu'on achète avec des magasines .
Bravo encore!
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
27 oct. 2003 à 03:36
Je constate que tu es un couche-tard, kimmelf2 !

Attention, comme disait ma grand-mère, jeunesse qui veille et vieillesse qui dort sont tous deux près de la mort ;)
C'est comme ça que j'ai décidé de ne plus dormir ! ptdrrrrr :))))))))

Ce bout de code, j'essayais de te l'expliquer, est destiné à être mis dans une boucle qui va s'occuper des fichiers à décrypter, de manière automatique.

Merci pour ton "bravo", j'en conclus que ça fonctionne, hein ? (manquerait plus que ça marche pas...)

Ultra-mini-débutant deviendra grand, t'en fais pas !

Bonne prog', faut pas mollir !!!!
kimmelf2 Messages postés 267 Date d'inscription lundi 22 septembre 2003 Statut Membre Dernière intervention 27 novembre 2005
27 oct. 2003 à 03:04
bah pas speciallement, c'etais + un conseil, car c'est un pgm pour decrypter des images jpg, lesquelles sont generallement fournies par paquets. alors si il faut lancer le pgm pour chaque image, on s'en sort pas donc le pgm n'est pas completement adapte au "probleme" de base, donc des points en moin ! :-D

Franchement, je te dis qd meme bravo car moi je suis qu'un ultra-mini-debutant en delphi, et j'aurais pas reussi a faire juste la fonction de base du decodage alors ...
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
25 oct. 2003 à 00:14
Que tu es impatient, kimmelf2 !

Mets donc un OpenDialog avec la propriété multiselect, en attendant...
Ou une recherche récursive de tous les fichiers comportant l'extension .jpg se trouvant dans un répertoire sélectionné.

Sinon, patiente, comme dit plus haut, j'y reviendrai, mais j'ai pas trop le temps...

Ah, quand les hormones nous travaillent... mdr :)
kimmelf2 Messages postés 267 Date d'inscription lundi 22 septembre 2003 Statut Membre Dernière intervention 27 novembre 2005
24 oct. 2003 à 23:51
et puis une petite option toute simple mais ca fais toujours un + : l'application du decryptage a plusieurs images, voire a tout un dossier ...

:-D
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
24 oct. 2003 à 00:36
Oui, Delphiprog, je suis sur que ça va en intéresser plus d'un(e) ;)

Le positionnement de mes blocs try..except et try..finally me semblait logique... il faut que j'étudie ça à tête reposée.

Le thread, c'est prévu, et pourquoi pas plusieurs threads qui se partageraient le travail (ouh la la, la complication... :( )

J'avais déjà fait un programme tout à fait fonctionnel, mais le code me fait un peu honte, maintenant. Je crois que je vais m'y remettre, c'est un bon exercice de programmation.

Merci pour tes conseils et encouragements Delphiprog :)
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
24 oct. 2003 à 00:06
Alors comme çà, la protection est limitée à une simple opération logique XOR ?
Trouve nous vite une solution pour accélérer le décodage.
Je suis sur que ça va en intéresser plus d'un !

NB : le positionnement des mots réservés Try et Finally ne me semble pas judicieux et approprié. Deux instructions try qui se suivent l'une derrière l'autre...ne peuvent que se ressembler.
Dans le cas présent, si un erreur se produit en voulant lire le premier fichier, tu essaies de fermer les deux alors que le deuxième n'est pas encore assigné. Gag !
Cette remarque vaut aussi bien pour la procédure Decrypte que DecodeFichier.

Et puis, si c'est si long, pourquoi ne pas mettre tout celà dans un thread séparé ?
Bon courage Japee, le plus dur est déjà fait. ;o)
Rejoignez-nous