C版OpenSSL EVP_BytesToKey方法

我正在寻找OpenSSL EVP_BytesToKey函数的C实现。

这是EVP_BytesToKey方法的伪代码解释(在OpenSSL源的/doc/ssleay.txt中):

 /* M[] is an array of message digests * MD() is the message digest function */ M[0]=MD(data . salt); for (i=1; i<count; i++) M[0]=MD(M[0]); i=1 while (data still needed for key and iv) { M[i]=MD(M[i-1] . data . salt); for (i=1; i<count; i++) M[i]=MD(M[i]); i++; } If the salt is NULL, it is not used. The digests are concatenated together. M = M[0] . M[1] . M[2] ....... 

这是我的代码(MD()是sha512。我需要密钥是32个字节,iv是16个字节):

 int main() { unsigned long long out[8]; unsigned char key[9] = {0x4b,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c}; int len, i; len = sizeof(key); sha512(out, key, len); unsigned char a[sizeof(out)]; for (i = 0; i < count; i++) { long2char(out, a); // unsigned long long to unsigned char; sha512(out, a, sizeof(out)); } return 0; } 

count次数sha512() ,out是64个字节,所以我想我不需要其余的伪代码。 但结果不正确,我不知道出了什么问题。

我希望你能帮助我弄明白。 谢谢!

我正在寻找OpenSSL EVP_BytesToKey函数的C实现…

也许你应该只使用一个OpenSSL提供的? 你知道,在EVP_BytesToKeyevp_key.c (如下所示)。

OpenSSL 1.1.0c改变了一些内部组件中使用的摘要算法 。 以前使用MD5,1.1.0切换到SHA256。 请注意,在EVP_BytesToKey和openssl enc等命令中,更改不会影响您


 int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, const unsigned char *salt, const unsigned char *data, int datal, int count, unsigned char *key, unsigned char *iv) { EVP_MD_CTX *c; unsigned char md_buf[EVP_MAX_MD_SIZE]; int niv, nkey, addmd = 0; unsigned int mds = 0, i; int rv = 0; nkey = EVP_CIPHER_key_length(type); niv = EVP_CIPHER_iv_length(type); OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH); OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH); if (data == NULL) return nkey; c = EVP_MD_CTX_new(); if (c == NULL) goto err; for (;;) { if (!EVP_DigestInit_ex(c, md, NULL)) goto err; if (addmd++) if (!EVP_DigestUpdate(c, &(md_buf[0]), mds)) goto err; if (!EVP_DigestUpdate(c, data, datal)) goto err; if (salt != NULL) if (!EVP_DigestUpdate(c, salt, PKCS5_SALT_LEN)) goto err; if (!EVP_DigestFinal_ex(c, &(md_buf[0]), &mds)) goto err; for (i = 1; i < (unsigned int)count; i++) { if (!EVP_DigestInit_ex(c, md, NULL)) goto err; if (!EVP_DigestUpdate(c, &(md_buf[0]), mds)) goto err; if (!EVP_DigestFinal_ex(c, &(md_buf[0]), &mds)) goto err; } i = 0; if (nkey) { for (;;) { if (nkey == 0) break; if (i == mds) break; if (key != NULL) *(key++) = md_buf[i]; nkey--; i++; } } if (niv && (i != mds)) { for (;;) { if (niv == 0) break; if (i == mds) break; if (iv != NULL) *(iv++) = md_buf[i]; niv--; i++; } } if ((nkey == 0) && (niv == 0)) break; } rv = EVP_CIPHER_key_length(type); err: EVP_MD_CTX_free(c); OPENSSL_cleanse(md_buf, sizeof(md_buf)); return rv; }