Страницы

пятница, 4 февраля 2011 г.

Использование алгоритма AES при помощи библиотеки openssl

Столкнулся с тем, что нет описания интерфейс к алгоритму AES в библиотеке OpenSSL, а несколько русскоязычных статей оказались мало пригодно, по тому простому поводу, что в примерах давали не работающий код. Хотя нельзя отрицать, что там была и полезная информация, которая помогла лучше понять англоязычную документацию на openssl.org .
Собственно функция фишрования :
unsigned long int do_crypt(unsigned char *infile,int inlen ,unsigned char * key)
{
// unsigned char key[32]; /* 256- битный ключ */
unsigned char *last_buf;//for last bytes that is
int sum_len=0;
int outlen=0;
EVP_CIPHER_CTX ctx;
const EVP_CIPHER * cipher;
/* Обнуляем структуру контекста */
EVP_CIPHER_CTX_init(&ctx);
/* Выбираем алгоритм шифрования */
cipher = EVP_aes_256_cbc();
/* Инициализируем контекст алгоритма */
EVP_EncryptInit(&ctx, cipher, key, NULL);
/* Шифруем данные */
last_buf=infile;
if(!EVP_EncryptUpdate(&ctx, last_buf, &outlen, infile,inlen ) ) return 0;
sum_len+=outlen;
last_buf=infile+outlen;
if(!EVP_EncryptFinal(&ctx, last_buf, &outlen)) return 0;
sum_len+=outlen;
EVP_CIPHER_CTX_cleanup(&ctx);
return sum_len;//возвращаем длину зашифрованых данных



};
Собственно функция принимает указатель на строку, которую надо зашифровать, длинну строки и ключ ( 256 бит в данном случае). Данная функция справляется нормально с шифрованием данных до 65 мегабайт, больше не тестировал. Возвращает длину зашифрованных данных, которая может отличаться от исходной длинны.
Функция дешифрования :

int do_decrypt(unsigned char *infile,int inlen,unsigned char * key)
{
unsigned char *last_buf;//for last bytes that is
int outlen,sum_len,temp_len,last;


EVP_CIPHER_CTX ctx;

const EVP_CIPHER * cipher;
/* Обнуляем структуру контекста */
EVP_CIPHER_CTX_init(&ctx);
/* Выбираем алгоритм шифрования */

cipher = EVP_aes_256_cbc();
/* Инициализируем контекст алгоритма */
EVP_DecryptInit(&ctx, cipher, key, NULL);
outlen=temp_len=0;
last_buf=infile;
if(!EVP_DecryptUpdate(&ctx, last_buf, &outlen,infile, inlen)) return 0;
memcpy(infile,last_buf,outlen);
last_buf=infile+outlen;
if(!EVP_DecryptFinal(&ctx, last_buf, &temp_len)) return 0;
memcpy(infile+outlen,last_buf,temp_len);

EVP_CIPHER_CTX_cleanup(&ctx);

return outlen+temp_len;
}


Параметры аналогичные только с префиксов "де". В обоих функциях использует одна и та же область памяти для шифрования и дешифрования. При дешифровке будет возвращен размер расшифрованных данных, за областью этого размера сохранится всякая белеберда которую надо будет обрезать например таким вот образом:

*(infile+outlen+temp_len)='\0';