#encryption #hash #openssl #md5
Вопрос:
Я новичок в OpenSSL и в настоящее время работаю над проектом на C , который зависит от OpenSSL. Недавно я начал использовать машину, на которой был установлен OpenSSL 3.0, но не смог создать проект, потому что я получаю ошибки компилятора, как показано ниже (обратите внимание, что предупреждения рассматриваются как ошибка в проекте)
error: 'MD5' is deprecated
if (!MD5((uint8_t*)key.data(), key.size(), hashOutput)) {
^
/usr/local/Cellar/openssl@3/3.0.0_1/include/openssl/md5.h:52:1: note: 'MD5' has been explicitly marked deprecated here
OSSL_DEPRECATEDIN_3_0 unsigned char *MD5(const unsigned char *d, size_t n,
^
/usr/local/Cellar/openssl@3/3.0.0_1/include/openssl/macros.h:182:49: note: expanded from macro 'OSSL_DEPRECATEDIN_3_0'
# define OSSL_DEPRECATEDIN_3_0 OSSL_DEPRECATED(3.0)
^
/usr/local/Cellar/openssl@3/3.0.0_1/include/openssl/macros.h:62:52: note: expanded from macro 'OSSL_DEPRECATED'
# define OSSL_DEPRECATED(since) __attribute__((deprecated))
^
1 error generated.
Проведя некоторое расследование, я обнаружил, что эти API устарели в OpenSSL 3.0.0, и теперь у меня есть три варианта
- Игнорируйте предупреждения. Это просто предупреждения. Устаревшие функции все еще присутствуют, и вы все равно можете их использовать. Однако имейте в виду, что они могут быть удалены из будущей версии OpenSSL.
- Подавите предупреждения. Обратитесь к документации вашего компилятора о том, как это сделать.
- Удалите использование низкоуровневых API. В этом случае вам нужно будет переписать свой код, чтобы вместо него использовать API высокого уровня.
Я выбираю третий вариант, но даже после прочтения документации, связанной с OpenSSL, я все еще не уверен, какой EVP API эквивалентен методу MD5, который устарел в OpenSSL 3.0.0. Если вы проверите ссылку https://www.openssl.org/docs/manmaster/man3/MD5.html в нем говорится , что
Все функции, описанные на этой странице, устарели. Приложения должны вместо этого использовать EVP_DigestInit_ex(3), EVP_DigestUpdate(3) и EVP_DigestFinal_ex(3).
Было бы здорово, если бы кто-нибудь мог предоставить мне некоторую обратную связь / помощь или дополнительные ресурсы / ссылки, которые могли бы помочь мне понять использование высокоуровневого OpenSSL API в целом, чтобы я мог заставить его работать для моего варианта использования, например, шифрования MD5.
Я должен также упомянуть, что я загрузил OpenSSL repo с github и обнаружил, что реализация метода md5 выглядит следующим образом
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md)
{
MD5_CTX c;
static unsigned char m[MD5_DIGEST_LENGTH];
if (md == NULL)
md = m;
if (!MD5_Init(amp;c))
return NULL;
#ifndef CHARSET_EBCDIC
MD5_Update(amp;c, d, n);
#else
{
char temp[1024];
unsigned long chunk;
while (n > 0) {
chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
ebcdic2ascii(temp, d, chunk);
MD5_Update(amp;c, temp, chunk);
n -= chunk;
d = chunk;
}
}
#endif
MD5_Final(md, amp;c);
OPENSSL_cleanse(amp;c, sizeof(c)); /* security consideration */
return md;
}
Комментарии:
1. Вы можете найти пример использования высокоуровневых хэш-функций в документации . Это для SHA256, но может быть применено к MD5 полностью аналогичным образом с помощью
EVP_md5()
. Обратите внимание, однако, что MD5 обычно небезопасен, например, здесь .2. если я правильно понимаю, это означает, что мне нужно реализовать подобный метод
void digest_message(const unsigned char *message, size_t message_len, unsigned char **digest, unsigned int *digest_len)
, и нет доступного EVP_ эквивалента MD5, правильно ли я понимаю.3. Afaik, OpenSSL не предоставляет метод, который уже выполняет это, т. Е. Вы должны реализовать его самостоятельно: скопируйте метод из документации и замените два
EVP_sha256()
вызоваEVP_md5()
вызовами.
Ответ №1:
Я надеюсь, что этот пример поможет (я не проверяю ошибки и исключения в моем примере, поэтому имейте это в виду):
Устаревшая реализация
#include <openssl/md5.h>
static void calculate_md5(unsigned char* buf, unsigned int buf_size)
{
unsigned char md5_digest[MD5_DIGEST_LENGTH];
MD5_CTX md5ctx;
MD5_Init(amp;md5ctx);
MD5_Update(amp;md5ctx, buf, buf_size);
MD5_Final(md5_digest, amp;md5ctx);
}
Новая реализация:
#include <openssl/evp.h>
static void calculate_md5(unsigned char* buf, unsigned int buf_size)
{
EVP_MD_CTX *mdctx;
unsigned char *md5_digest;
unsigned int md5_digest_len = EVP_MD_size(EVP_md5());
// MD5_Init
mdctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);
// MD5_Update
EVP_DigestUpdate(mdctx, buf, buf_size);
// MD5_Final
md5_digest = (unsigned char *)OPENSSL_malloc(md5_digest_len);
EVP_DigestFinal_ex(mdctx, md5_digest, amp;md5_digest_len);
EVP_MD_CTX_free(mdctx);
}