Chiffrement AES
Deux API de chiffrement AES:
- AES_cbc_encrypt
- EVP_Encrypt
Cette dernière API intégre deux fonctions intéressantes :
- Fournir la taille de la chaine d'origine surtout utile lorsque le cryptage utilise un padding
- Valide que la clef de décryptage est celle attendue.
Méthode avec AES_cbc_encrypt
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <openssl/sha.h>
#include <openssl/rand.h>
#include <Windows.h>
#include <assert.h>
#include <openssl/err.h>
#define BIG_TEST_SIZE 10240
static void hexdump(FILE *f,const char *title,const unsigned char *s,int l)
{
int n=0;
fprintf(f,"%s",title);
for( ; n < l ; ++n)
{
if((n%16) == 0)
fprintf(f,"\n%04x",n);
fprintf(f," %02x",s[n]);
}
fprintf(f,"\n");
}
int main(int argc, char* argv[])
{
const KEYSIZE=AES_BLOCK_SIZE;
char rkey[KEYSIZE+1];
char rkey2[KEYSIZE+1];
AES_KEY key;
AES_KEY key2;
char plaintext[BIG_TEST_SIZE];
char ciphertext[BIG_TEST_SIZE];
char checktext[BIG_TEST_SIZE];
char iv[AES_BLOCK_SIZE*4];
char saved_iv[AES_BLOCK_SIZE*4];
int err = 0;
int n;
RAND_pseudo_bytes((unsigned char*)rkey, sizeof rkey);
strcpy(iv,"0123456789012345");
memcpy(saved_iv, iv, sizeof saved_iv);
strcpy((char*)plaintext,"string to make the random number generator think it has entropy");
// Straight encrypt
AES_set_encrypt_key((unsigned char*)rkey, 8*KEYSIZE, &key);
hexdump(stdout, "plaintext", (unsigned char*)plaintext, strlen(plaintext));
AES_cbc_encrypt((unsigned char*)plaintext, (unsigned char*)ciphertext, strlen(plaintext), &key, (unsigned char*)iv,AES_ENCRYPT);
hexdump(stdout, "ciphertext", (unsigned char*)ciphertext, strlen(plaintext));
// Straight decrypt
AES_set_decrypt_key((unsigned char*)rkey, 8*KEYSIZE, &key);
memcpy(iv, saved_iv, sizeof iv);
AES_cbc_encrypt((unsigned char*)ciphertext, (unsigned char*)checktext, strlen(plaintext), &key, (unsigned char*)iv,AES_DECRYPT);
hexdump(stdout, "checktext", (unsigned char*)checktext, strlen(plaintext));
return 0;
}
Méthode avec EVP
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <openssl/sha.h>
#include <openssl/rand.h>
#include <Windows.h>
#include <assert.h>
#include <openssl/err.h>
static void hexdump
(FILE *f,
const char *title,
const unsigned char *s,
int l
)
{
int n=
0;
fprintf
(f,
"%s",title
);
for( ; n < l ; ++n
)
{
if((n%
16) ==
0)
fprintf
(f,
"\n%04x",n
);
fprintf
(f,
" %02x",s
[n
]);
}
fprintf
(f,
"\n");
}
int main
(int argc,
char* argv
[])
{
unsigned char outbuf2
[1024];
unsigned char outbuf
[1024];
int outlen, outlen2, tmplen;
unsigned char key
[] =
{0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15};
unsigned char iv
[] =
{1,
2,
3,
4,
5,
6,
7,
8};
char intext
[] =
"string to make the random number generator think it has entropy";
hexdump
(stdout,
"plaintext",
(unsigned char*
)intext, strlen
(intext
));
// Straight encrypt
EVP_CIPHER_CTX x;
EVP_CIPHER_CTX_init
(&x
);
if(!EVP_EncryptInit_ex
(&x, EVP_aes_
128_cbc
(),
NULL, key, iv
))
printf("\n ERROR!! \n");
if(!EVP_EncryptUpdate
(&x, outbuf, &outlen,
(const unsigned char*
) intext, strlen
(intext
)))
printf("\n ERROR!! \n");
if(!EVP_EncryptFinal_ex
(&x,outbuf+outlen,&tmplen
))
printf("\n ERROR!! \n");
outlen+=tmplen;
hexdump
(stdout,
"ciphertext", outbuf, outlen
);
EVP_CIPHER_CTX_cleanup
(&x
);
// Straight decrypt
tmplen=
0;
outlen2=
0;
EVP_CIPHER_CTX_init
(&x
);
EVP_DecryptInit_ex
(&x, EVP_aes_
128_cbc
(),
NULL, key, iv
);
if(!EVP_DecryptUpdate
(&x, outbuf2, &outlen2,
(const unsigned char*
) outbuf, outlen
))
printf("\n ERROR!! \n");
if(!EVP_DecryptFinal_ex
(&x, outbuf2 + outlen2, &tmplen
)){
unsigned long error, reason,err;
char buf
[128];
error = ERR_peek_error
();
reason = ERR_GET_REASON
(error
);
//EVP_R_BAD_DECRYPT
ERR_error_string_n
(reason,buf,
128);
printf("%s",buf
);
}
outlen2+=tmplen;
hexdump
(stdout,
"checktext", outbuf2, outlen2
);
EVP_CIPHER_CTX_cleanup
(&x
);
}