Как использовать bcrypt в OpenSSL?
Я хочу использовать шифрование bcrypt для хранения паролей, и я знаю, что OpenSSL реализует Blowfish Cipher (что я предполагаю, это то же самое).
Я сделал некоторые изменения из кода, показанного на этой странице https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption и придумал это:
int OpenSSLEncrypt(
unsigned char* plaintext,
int plaintext_len,
unsigned char* key,
unsigned char* iv,
unsigned char* ciphertext)
{
EVP_CIPHER_CTX *ctx;
int len;
int ciphertext_len;
if (!(ctx = EVP_CIPHER_CTX_new())) OpenSSLHandleErrors();
if (1 != EVP_EncryptInit_ex(ctx, EVP_bf_cbc(), 0, key, 0))
OpenSSLHandleErrors();
if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
OpenSSLHandleErrors();
ciphertext_len = len;
if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
OpenSSLHandleErrors();
ciphertext_len += len;
/* Clean up */
EVP_CIPHER_CTX_free(ctx);
return ciphertext_len;
}
int OpenSSLDecrypt(
unsigned char* ciphertext,
int ciphertext_len,
unsigned char* key,
unsigned char* iv,
unsigned char* plaintext)
{
EVP_CIPHER_CTX *ctx;
int len;
int plaintext_len;
if (!(ctx = EVP_CIPHER_CTX_new())) OpenSSLHandleErrors();
if (1 != EVP_DecryptInit_ex(ctx, EVP_bf_cbc(), NULL, key, 0))
OpenSSLHandleErrors();
if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
OpenSSLHandleErrors();
plaintext_len = len;
if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len))
OpenSSLHandleErrors();
plaintext_len += len;
/* Clean up */
EVP_CIPHER_CTX_free(ctx);
return plaintext_len;
}
Но длина шифра, который я получаю из OpenSSLEncrypt(...), зависит от длины входного параметра открытого текста, а это не то, что я ожидал. Я ожидал, что вывод будет длиной 64 байта независимо от длины пароля.
Кроме того, я не знаю, нужен ли EVP_EncryptInit_ex iv (вектор инициализации) или нет для EVP_bf_cbc, и я не нашел документации, которая могла бы помочь мне в этом.
2 ответа
Как было отмечено в комментариях, я ошибался, полагая, что Blowfish и BCrypt - это одно и то же, просто потому, что я где-то читал, B означает Blowfish.
Я закончил тем, что следовал предложению Cinder Biscuits об использовании реализации bcrypt в OpenBSD, доступной в
https://github.com/libressl-portable/openbsd/blob/master/src/lib/libc/crypt/bcrypt.c
https://github.com/openssl/openssl/issues/5323 <- openssl говорит, что они не будут поддерживать bcrypt – подробности прочитайте в билете