Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Delphi Discussion :

Crypter un fichier byte à byte : Epilogue 2


Sujet :

Contribuez Delphi

  1. #1
    Membre habitué
    Crypter un fichier byte à byte : Epilogue 2
    Soit deux collections compactes d’octets quelconques bien rangées à deux endroits distincts de la mémoire vive d’un ordinateur fonctionnant sous système Windows. On se donne comme tâche de « transformer » chacun des octets de la première en fonction de la teneur de ceux de la seconde de telle sorte qu’ils ne soient plus reconnaissables, mais qu’ils puissent redevenir ce qu’ils étaient avec la même « transformation ».

    Cela s’appelle du cryptage/décryptage par clé !

    Côté algorithme de « transformation », celui-ci n’a que faire des significations respectives des messages contenus par les deux collections ; ils peuvent être n’importe quoi. Ce qui compte pour lui est que la nature de la « transformation » ne donnera pratiquement aucune prise à la cryptanalyse. Alors on peut imaginer un cryptage par procédé dit de Vernam alimenté par un double générateur congruentiel de nombres pseudo-aléatoires dont la génération non spontanée est rendue dépendante du résultat d’une fonction de hachage des octets de la clé. Simple…

    Rien n’interdit que cet algorithme de cryptage/décryptage soit englobé dans une toute petite DLL qui pourrait être utilisable par Delphi bien sûr mais aussi par d’autres langages sous Windows… Alors voici cette DLL compilable par Delphi :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    library CryptoV64;
     
    uses
       Windows;
    // Routine exportable *******************************************************
     
    procedure CrypteV64(PBuff,PKey: pointer; SizeBuf,SizeKey: longWord); stdCall;
    var Al1,Al2 : longInt;
    asm
        push     ebx
        push     esi
        mov      esi,[ebp+$08]
        push     edi
        mov      edi,[ebp+$0C]
        mov      ebx,Dword ptr[edi]
        mov      eax,Dword ptr[edi+4]
        xor      ecx,ecx
        mov      ecx,[ebp+$14]
        sub      ecx,$8
        jbe      @Xorise
        add      edi,$09
        @Sert:
              xor      edx,edx
              mov      dl,byte ptr[edi]
              test      dl,dl
              jnz       @NZ
              or        dl,$FF
              @NZ:
              mul      edx
              add      ebx,edx
              inc      edi
              loop     @Sert
        @Xorise:
        mov      Al1,ebx
        mov      Al2,eax
        mov      ecx,[ebp+$10]
        shr      ecx,$3
        jz       @Reste
        @XorQWords:
              xor     DWord ptr[esi],ebx
              add     esi,$4
              xor     DWord ptr[esi],eax
              add     esi,$4
              xor     eax,eax
              dec     eax
              imul    edx,Al1,$08088405
              inc     edx
              mov     Al1,edx
              mul     edx
              mov     ebx,edx
              xor     eax,eax
              dec     eax
              imul    edx,Al2,$08088405
              inc     edx
              mov     Al2,edx
              mul     edx
              mov     eax,edx
              loop    @XorQWords
        @Reste:
        mov      ecx,[ebp+$10]
        and      ecx,$7
        jz       @Fin
        @XorBytes:
              xor    Byte ptr[esi],al
              inc    esi
              mov    al,bl
              shr    ebx,$8
              ror    eax,$8
              loop   @XorBytes
        @Fin:
        pop      edi
        pop      esi
        pop      ebx
    end;
     
    exports
        CrypteV64;
     
    begin
    end.


    Pour ceux qui ne sont pas familiarisés avec les librairies en Delphi, il suffit d’ouvrir un nouveau projet, d’y supprimer l’unit1 fournie puis de remplacer le code source du projet fourni par le code ci-dessus ; ensuite la compilation de ce projet va produire en répertoire de travail un fichier dénommé CryptoV64.dll.

    L’unique procédure de cette dll n’attend pour faire sont job que 4 paramètres : un pointeur sur le premier octet du buffer à crypter, un pointeur sur le premier octet du buffer de clé, la quantité d’octets du buffer à crypter et enfin la quantité d’octets du buffer de clé et l’opération de « transformation » ne nécessitera qu’une fraction de seconde pour s’accomplir car elle travaille en 2x32 bits.

    Comment s’en servir dans un projet-programme en Delphi pour crypter un fichier ?

    1/ Placer CryptoV64.dll dans le même répertoire que lui.

    2/ Pour assurer la liaison avec la fonction de cryptage/décryptage contenue en dll, placer dans la partie Implementation du programme la déclaration suivante :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    procedure CrypteV64(PBuf,PKey: pointer; SizeBuf,SizeKey: longWord); stdCall; external'CryptoV64';


    3/ Déclarer la clef de cryptage dans une String :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    MaClef : String ;
    MaClef :='Les sanglots longs des violons de l''automne' ;


    4/ Appeler le fichier à crypter/décrypter dans un buffer de type TMemoryStream

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    MonStream : TMemoryStream ;
    MonStream :=TMemoryStream.Create ;
    MonStream.LoadFromFile('MonFichier.dat');


    5/ Crypter ou décrypter avec

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    CrypteV64(MonStream.Memory, @MaClef[1], MonStream.Size, length(Maclef));


    6/ sauver le fichier crypté/décrypté et libérer la RAM
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    MonStream.SaveToFile('MonFichierCrypté.dat') ;
    MonStream.free ;


    Commentaires :

    Les "conteneurs" de fichiers et clés peuvent être divers (array, buffers réservés en RAM, String longues etc...)
    La clé doit avoir plus de 8 octets, en deçà, le cryptage aura lieu, mais le décryptage sera impossible.
    La clé utilisée lors du décryptage doit être exactement identique au bit près à celle ayant servi au cryptage.

    N.B. Pour ceux qui répugnent à l'emploi des dll, il est possible ici de copier-coller la procédure de cryptage en programme Delphi.

  2. #2
    Rédacteur/Modérateur

    Bonjour ! Merci pour cette contribution qui mériterait (me semble-t-il) de figurer dans nos Sources Delphi.

    Pour ma part, j'ai testé le code avec Delphi 7. Chapeau !

  3. #3
    Modérateur

    Bonjour,

    Roland Chastain : Merci pour cette contribution qui mériterait (me semble-t-il) de figurer dans nos Sources Delphi.
    Pour ma part, j'ai testé le code avec Delphi 7. Chapeau !
    Entièrement d'accord, et pour ma part, j'ai testé le code avec Delphi 6 de deux manières :
    - avec la procédure CrypteV64( ....) placée directement dans la partie implémentation du programme d'utilisation,
    - puis, après l'y avoir suprimée, en utilisant la DLL.

    Résultats de tests comparatifs de vitesse pour le cryptage d'un fichier-image 50 Mo (BitMap de 5120x2560x16MillionsDeCouleurs) :
    - avec Vigenère : mis 203 millisecondes,
    - avec Substitution simple : mis 62 ms
    - avec CrypteV64 de Rekin85 : mis 31 millisecondes, avec une Clef de 512 caractères
    - et tout ça avec un Intel Core i7-2700K à 3,5 GHz.

    Comme déjà dit qu'avec une Clef de seulement 73 caractères ça donnait au moins 200^73 = 9,4447E167 clefs possibles et qu'un Hacker utilisant un ordinateur essayant 1 million de clefs par seconde mettrait des Milliards de Milliards d'années pour essayer de décrypter... et qu'avec une Clef de 512 caractères on peut obtenir au moins 200^512 = 1,3408E1178 clefs possibles je pense qu'avec ça on est tranquilles pendant quelques Milliards de siècles !!!.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  4. #4
    Membre habitué
    Merci Roland et Gilbert pour vos tests.
    Je me dois de signaler que cet algorithme de cryptage un peu particulier est le résultat de recherches communes que nous avons menées conjointement Gilbert et moi sur ce sujet.

  5. #5
    Modérateur

    Bonjour,

    René : Je me dois de signaler que cet algorithme de cryptage un peu particulier est le résultat de recherches communes que nous avons menées conjointement Gilbert et moi sur ce sujet
    C'est très sympa de me renvoyer l'ascenseur, mais je me dois de signaler à mon tour que lors de ces recherches ma contribution s'est limitée à apporter quelques idées d'amélioration dont certaines ont été intégrées dans les versions successives qui ont abouti à la CryptoV64 codée en ASM, ASM que je ne maîtrise pas, et qu'à part ceci ma part de recherches communes est restée dans le domaine du sur-cryptage avec des routines codées sous Delphi et sans ASM.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  6. #6
    Membre habitué
    Bonjour à tous

    J'ai effectué une petite mise à jour mineure sur le code de la dll afin d'éviter les déboires d'une éventuelle utilisation de clé contenant des zéros. Ce qui pourrait se produire si on utilisait une autre chose qu'une string Delphi.

  7. #7
    Expert confirmé
    Jei,

    CryptoV64.dll est un nom pour le moins curieux, vu que le calcul utilise les registres 32 bits.

    Le mysticisme est une maladie qui crée des problèmes là où il n’en existe pas.

  8. #8
    Membre habitué
    Bonsoir droggo,

    Oui c'est du calcul 32 bits sur processeur X86. Mais le cryptage en lui-même se réalise sur 2 registres différents et sur 2 générateurs de pseudo aléatoires distincts; donc on est sur un chiffrage en QWords, d'ou le V64 (Vernam sur 64 bits), ce qui ne veut pas dire qu'il s'agisse d'une procedure en 64 bits...

  9. #9
    Expert confirmé
    Zie,

    Ok.

    Pour éviter la confusion, il aurait été préférable d'utiliser Crypto_V64 pour le nom.
    Le mysticisme est une maladie qui crée des problèmes là où il n’en existe pas.

  10. #10
    Membre habitué
    Hum, bonjour...

    Existerait-il une convention de nomenclature qui me ferait défaut ?

    Etant maintenant publiée en code source accessible, tout un chacun peut compiler cette dll avec le nom qu'il veut.

  11. #11
    Modérateur

    Bonjour,

    Droggo: Pour éviter la confusion, il aurait été préférable d'utiliser Crypto_V64 pour le nom
    En quoi et avec quoi cela éviterait-t-il la confusion en ajoutant le _ dans le nom actuel CryptoV64 ??? Y'a là une subtilité qui m'échappe !!!.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  12. #12
    Expert confirmé
    Kia,
    Citation Envoyé par Gilbert Geyer Voir le message
    Bonjour,


    En quoi et avec quoi cela éviterait-t-il la confusion en ajoutant le _ dans le nom actuel CryptoV64 ??? Y'a là une subtilité qui m'échappe !!!.

    A+.
    Voir plus haut le message #8 de ce sujet.
    Le mysticisme est une maladie qui crée des problèmes là où il n’en existe pas.