Bonjour à tous,


Edit: J'ai trouvé d'où venait le problème grâce à la simplification faite pour pouvoir poster le code ici.
Argh! J'ai perdu trois jours à cause de cette con**** !!!


Désolé pour le titre, mais comme je ne sais justement pas d'où viens le problème, je suis infoutu de trouver un titre potable.

J'essaye d'utiliser les fonctions de chiffrement d'OpenSSL, à savoir les fonctions EVP & Cie. J'ai été assez surpris du peu de documentation et/ou d'exemple sur le sujet. Après avoir cherché en vain un peu partout, je me tourne vers vous.

Mon problème, c'est que d'une exécution sur l'autre, le chiffrement du même message avec la même clef ne donne pas le même résultat. Cela ne me gênerai pas (et même me plairait beaucoup) si les messages chiffrés par une exécution précédente n'était plus déchiffrable par la suivante. Comme si il y avait un paramètre aléatoire qui affecte le processus de chiffrement/déchiffrement. Pire, si je place le code de chiffrement dans une fonction, chaque appel donne un résultat différent et je ne peux donc plus déchiffrer le message même si le chiffrement et le déchiffrement se trouve au sein de la même exécution.

Pour couronner le tout, les symptômes ne sont pas les mêmes en fonction de la plateforme. Le comportement décrit est celui sous Windows. Sous Unix (HP-UX), c'est plus vicieux : j'ai le même résultat d'une exécution sur l'autre tant que je ne modifie pas le programme ! Si je fais une modif, je peux me retrouver avec un résultat différent.

Voici mon code, simplifié à l'extrême. Sous Windows, on voit bien que les deux opération de chiffrement ne donne pas le même résultat et l'opération de déchiffrement plante.

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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
 
#include <iostream>
#include <iomanip>
#include <exception>
#include <stdexcept>
 
using namespace std;
 
#include "openssl/evp.h"
#include "openssl/rsa.h"
#include "openssl/err.h"
 
 
void buffer_dump(const unsigned char* buffer, size_t size)
{
  std::cout << hex;
  for (unsigned int i=0; i<size; i++)
    std::cout << (int) buffer[i] << " ";
  std::cout << dec << endl;
}
 
size_t EVP_ENCRYPT(unsigned char* bufferOut, int sizeOutput, const unsigned char* bufferIn, int sizeInput)
{
  EVP_CIPHER_CTX m_ctx;
  const char* key = "TESTKEY.........";
  unsigned char* buffer = bufferOut;
  size_t bufsize = 0;
 
  EVP_CIPHER_CTX_init(&m_ctx);
  EVP_EncryptInit_ex(&m_ctx, EVP_aes_256_cbc(), NULL, NULL, NULL);
  EVP_CIPHER_CTX_set_key_length(&m_ctx, ::strlen(key));
  if (EVP_EncryptInit_ex(&m_ctx, NULL, NULL, (const unsigned char*) key, NULL) != 1)
    std::cerr << "EVP_EncryptInit failed" << endl;
  if (EVP_EncryptUpdate(&m_ctx, bufferOut, &sizeOutput, bufferIn, sizeInput) != 1)
    std::cerr << "EVP_EncryptUpdate failed" << endl;
  bufferOut += sizeOutput;
  bufsize += sizeOutput;
  if (EVP_EncryptFinal_ex(&m_ctx, bufferOut, &sizeOutput) != 1)
    std::cerr << "EVP_EncryptFinal_ex failed" << endl;
  bufsize += sizeOutput;
  EVP_CIPHER_CTX_cleanup(&m_ctx);
  buffer_dump(bufferOut, bufsize);
  return bufsize;
}
 
size_t EVP_DECRYPT(unsigned char* bufferOut, int sizeOutput, const unsigned char* bufferIn, int sizeInput)
{
  EVP_CIPHER_CTX m_ctx;
  const char* key = "TESTKEY.........";
  unsigned char* buffer = bufferOut;
  size_t bufsize = 0;
 
  EVP_CIPHER_CTX_init(&m_ctx);
  EVP_DecryptInit_ex(&m_ctx, EVP_aes_256_cbc(), NULL, NULL, NULL);
  EVP_CIPHER_CTX_set_key_length(&m_ctx, ::strlen(key));
  if (EVP_DecryptInit_ex(&m_ctx, NULL, NULL, (const unsigned char*) key, NULL) != 1)
    std::cerr << "EVP_DecryptInit_ex failed" << endl;
  if (EVP_DecryptUpdate(&m_ctx, bufferOut, &sizeOutput, bufferIn, sizeInput) != 1)
    std::cerr << "EVP_DecryptUpdate failed" << endl;
  bufferOut += sizeOutput;
  bufsize += sizeOutput;
  if (EVP_DecryptFinal_ex(&m_ctx, bufferOut, &sizeOutput) != 1)
    std::cerr << "EVP_DecryptFinal_ex failed" << endl;
  bufsize += sizeOutput;
  EVP_CIPHER_CTX_cleanup(&m_ctx);
  buffer_dump(bufferOut, bufsize);
  return bufsize;
}
 
 
int main(int argc, char* argv[])
{
  const char* srctext = "TEST";
 
  unsigned char* bufferIn;
  unsigned char* bufferOut;
  int sizeBuffer = 0;
  int sizeOutput, sizeInput;
 
  char encbuffer[32];
  char decbuffer[32];
 
  bufferIn = (unsigned char*)(srctext);
  sizeInput = ::strlen(srctext);
  bufferOut = (unsigned char*)(encbuffer);
  sizeOutput = sizeof(encbuffer);
 
  sizeBuffer = EVP_ENCRYPT(bufferOut, sizeOutput, bufferIn, sizeInput);
  sizeBuffer = EVP_ENCRYPT(bufferOut, sizeOutput, bufferIn, sizeInput);
 
  bufferIn = (unsigned char*)(encbuffer);
  sizeInput = sizeBuffer;
  bufferOut = (unsigned char*)(decbuffer);
  sizeOutput = sizeof(decbuffer);
 
  sizeBuffer = EVP_DECRYPT(bufferOut, sizeOutput, bufferIn, sizeInput);
}
Merci de votre aide.