C 版本的 OpenSSL EVP_BytesToKey 方法 [英] C version of OpenSSL EVP_BytesToKey method

查看:294
本文介绍了C 版本的 OpenSSL EVP_BytesToKey 方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm looking for C implementation of the OpenSSL EVP_BytesToKey function.

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

This is pseudo-code explanation of the EVP_BytesToKey method (in /doc/ssleay.txt of the OpenSSL source):

/* 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 字节):

this is my code(MD() is sha512. And i need the key is 32 bytes and the iv is 16 bytes):

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;
}

countsha512() 之后,输出是 64 个字节,所以我想我不需要剩下的伪代码.但结果不正确,我不知道出了什么问题.

After count times sha512(), the out is 64 bytes, so I think I don't need the rest of that pseudo-code. But the result is not correct, I don't know what went wrong.

我希望你能帮我弄清楚.谢谢!

I wish you can help me to figure it out. thanks!

推荐答案

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

I'm looking for C implementation of the OpenSSL EVP_BytesToKey function...

也许您应该只使用 OpenSSL 提供的一个?你知道,在 EVP_BytesToKey 的那个>evp_key.c(如下所示).

Perhaps you should just use the one OpenSSL provides? You know, the one called EVP_BytesToKey in evp_key.c (shown below).

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

OpenSSL 1.1.0c changed the digest algorithm used in some internal components. Formerly, MD5 was used, and 1.1.0 switched to SHA256. Be careful the change is not affecting you in both EVP_BytesToKey and commands like 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;
}

这篇关于C 版本的 OpenSSL EVP_BytesToKey 方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆