Как сделать расшифровку AES с помощью OpenSSL
Я хотел бы использовать библиотеку OpenSSL для дешифрования некоторых данных AES. Код имеет доступ к ключу. Этот проект уже использует libopenssl для чего-то другого, поэтому я хотел бы придерживаться этой библиотеки.
Я посмотрел прямо в /usr/include/openssl/aes.h
, так как сайт OpenSSL освещен в документации. Единственная функция дешифрования - это:
void AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
К сожалению, у этого нет способа указать длину указателя in
, поэтому я не уверен, как это будет работать.
Есть несколько других функций, которые, как я полагаю, берут числовое расположение, чтобы различать шифрование и дешифрование. Например:
void AES_ecb_encrypt(*in, *out, *key, enc);
void AES_cbc_encrypt(*in, *out, length, *key, *ivec, enc);
void AES_cfb128_encrypt(*in, *out, length, *key, *ivec, *num, enc);
void AES_cfb1_encrypt(*in, *out, length, *key, *ivec, *num, enc);
void AES_cfb8_encrypt(*in, *out, length, *key, *ivec, *num, enc);
void AES_cfbr_encrypt_block(*in, *out, nbits, *key, *ivec, enc);
void AES_ofb128_encrypt(*in, *out, length, *key, *ivec, *num);
void AES_ctr128_encrypt(*in, *out, length, *key, ivec[], ecount_buf[], *num);
void AES_ige_encrypt(*in, *out, length, *key, *ivec, enc);
void AES_bi_ige_encrypt(*in, *out, length, *key, *key2, *ivec, enc);
Из того, что я понимаю с помощью Google, parm enc
устанавливается в AES_ENCRYPT
или AES_DECRYPT
, чтобы указать, какое действие должно выполняться.
Что приводит меня к моим двум вопросам:
- Что означают эти имена? Что такое ecb, cbc, cfb128 и т.д., И как я могу решить, какой из них я должен использовать?
- Что такое
unsigned char *ivec
parm, необходимый для большинства из них, и откуда его получить?
Ответы
Ответ 1
Нет размера, поскольку размеры блока для AES фиксированы на основе размера ключа; вы нашли реализацию ECB, которая не подходит для непосредственного использования (кроме как в качестве обучающего инструмента).
ЕЦБ, CBC, CFB128 и т.д. - все короткие имена для режимов работы, которые широко используются. У них разные свойства, но если вы никогда не касаетесь режима ECB, вы должны быть в порядке.
Я предлагаю остаться дальше от низкоуровневого кода; используйте EVP_*
интерфейсы, если сможете, и вы можете перенести некоторые из этих решений в текстовый файл конфигурации, чтобы ваши пользователи могли легко выбирать между различными шифрами, размеры блоков и режимы работы, если есть какая-то хорошая причина, чтобы отказаться от настроек по умолчанию.
Мои симпатии, документация OpenSSL чувствует себя хуже, чем есть, и это не так здорово. Вы можете найти Network Security с OpenSSL полезную книгу. Мне жаль, что я не нашел его раньше, чем в последний раз, когда мне нужно было использовать OpenSSL. (Не позволяйте глупому титулу дурачить вас - он должен был быть назван просто "OpenSSL". О, хорошо.)
Изменить Я забыл упомянуть векторы инициализации. Они используются, чтобы убедиться, что если вы зашифруете одни и те же данные с использованием одного и того же ключа, зашифрованный текст не будет идентичным. Вам нужно IV для расшифровки данных, но вам не нужно хранить секрет IV. Вы должны либо генерировать один случайный случай для каждого сеанса (и отправлять его вместе с RSA или El Gamal или DH-зашифрованным ключом сеанса), либо генерировать его одинаково на обеих конечных точках, или хранить его локально с файлом, что-то вроде этого.