问题
When I try to set the key length of an EVP_aes_128_cbc
envelope to 58, via EVP_CIPHER_CTX_set_key_length
, I get the following error:
3073369856:error:0607A082:digital envelope routines:EVP_CIPHER_CTX_set_key_length:invalid key length:crypto/evp/evp_enc.c:557:
That makes sense because EVP_aes_128_cbc only supports key sizes of 128 bits or 16 bytes.
What doesn't make sense to me is when I do the same thing for EVP_bf_cbc
I don't get any errors at all.
According to wikipedia's entry on Blowfish the maximum bitsize is 448 bits or 56 bytes, which is less than 58. Further, quoting http://etutorials.org/Programming/secure+programming/Chapter+5.+Symmetric+Encryption/5.18+Using+Variable+Key-Length+Ciphers+in+OpenSSL/, "OpenSSL puts a hard limit of 256 bits on key sizes".
My code:
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/crypto.h>
#include <string.h>
void handleErrors(void);
int main (void)
{
unsigned char *key = (unsigned char *)"0123456789012345678901234567890123456789012345678901234567";
unsigned char *iv = (unsigned char *)"01234567";
unsigned char *plaintext = (unsigned char *)"xxxxxxxx";
unsigned char ciphertext[128];
int plaintext_len = strlen((char *)plaintext);
int len;
EVP_CIPHER_CTX *ctx;
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
OPENSSL_config(NULL);
if (!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
if (!EVP_EncryptInit_ex(ctx, EVP_bf_cbc(), NULL, NULL, NULL)) handleErrors();
if (!EVP_CIPHER_CTX_set_key_length(ctx, 58)) handleErrors();
if (1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) handleErrors();
if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) handleErrors();
if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors();
EVP_CIPHER_CTX_free(ctx);
}
void handleErrors(void)
{
ERR_print_errors_fp(stderr);
abort();
}
Replace EVP_bf_cbc
with EVP_aes_128_cbc
to reproduce the error. I wouldn't be surprised if I got an error in EVP_EncryptInit_ex
(with EVP_aes_128_cbc
) since the iv isn't equal to the block size but the code is aborting before that point, anyway, so it's somewhat moot it seems to me.
回答1:
Using EVP_CIPHER_CTX_set_key_length()
is only helpful where a cipher has a variable key length (which is the case for Blowfish). The function does some limited validation on the supplied key length. If the cipher has a fixed length key, then it will check that the supplied key length is the same as the fixed length. Otherwise it will return with an error.
If using a cipher with a variable length key then it just checks that the key length is positive. Otherwise you can set any value that you like. It doesn't really make a difference because when Blowfish comes to use it, it checks that the key length is sane, and uses a reduced length if it is too long:
static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
BF_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
return 1;
}
...
void BF_set_key(BF_KEY *key, int len, const unsigned char *data)
#ifdef OPENSSL_FIPS
{
fips_cipher_abort(BLOWFISH);
private_BF_set_key(key, len, data);
}
void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data)
#endif
{
int i;
BF_LONG *p, ri, in[2];
const unsigned char *d, *end;
memcpy(key, &bf_init, sizeof(BF_KEY));
p = key->P;
if (len > ((BF_ROUNDS + 2) * 4))
len = (BF_ROUNDS + 2) * 4;
Here BF_ROUNDS == 16, so the maximum key length is 72 bytes (576 bits). I'm not particularly familiar with Blowfish, so I don't know why the discrepancy between this and the 448 bits you mention above.
Edit: Ah, the discrepancy is probably due to this (from wikipedia): "Because the P-array is 576 bits long, and the key bytes are XORed through all these 576 bits during the initialization, many implementations support key sizes up to 576 bits."
来源:https://stackoverflow.com/questions/41867197/evp-cipher-ctx-set-key-length-accepts-bad-sizes-for-blowfish