C# OpenSSL EVP_BytesToKey方法的C版本?

C# OpenSSL EVP_BytesToKey方法的C版本?,c#,.net,encryption,openssl,md5,C#,.net,Encryption,Openssl,Md5,我正在寻找OpenSSL函数的直接.NET实现。我发现的最接近的东西是类(and),但它似乎是,并且不生成与EVP_BytesToKey相同的键和iv 我还发现这似乎是一个好的开始,但没有考虑迭代计数 我意识到有OpenSSL.NET,但它只是原生OpenSSL DLL的包装,不是一个“真正的.NET实现”。我发现了EVP\u BytesToKey方法的伪代码解释(在OpenSSL源代码中): /*M[]是一个消息摘要数组 *MD()是消息摘要函数*/ M[0]=MD(data.salt); 对

我正在寻找OpenSSL函数的直接.NET实现。我发现的最接近的东西是类(and),但它似乎是,并且不生成与EVP_BytesToKey相同的iv

我还发现这似乎是一个好的开始,但没有考虑迭代计数


我意识到有OpenSSL.NET,但它只是原生OpenSSL DLL的包装,不是一个“真正的.NET实现”。

我发现了EVP\u BytesToKey方法的伪代码解释(在OpenSSL源代码中):

/*M[]是一个消息摘要数组
*MD()是消息摘要函数*/
M[0]=MD(data.salt);

对于(i=1;i谢谢你!还要记住,OpenSSL的默认运行使用
iterations=1
)。
/* 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] .......
private static void DeriveKeyAndIV(byte[] data, byte[] salt, int count, out byte[] key, out byte[] iv)
{
    List<byte> hashList = new List<byte>();
    byte[] currentHash = new byte[0];

    int preHashLength = data.Length + ((salt != null) ? salt.Length : 0);
    byte[] preHash = new byte[preHashLength];

    System.Buffer.BlockCopy(data, 0, preHash, 0, data.Length);
    if (salt != null)
        System.Buffer.BlockCopy(salt, 0, preHash, data.Length, salt.Length);

    MD5 hash = MD5.Create();
    currentHash = hash.ComputeHash(preHash);          

    for (int i = 1; i < count; i++)
    {
        currentHash = hash.ComputeHash(currentHash);            
    }

    hashList.AddRange(currentHash);

    while (hashList.Count < 48) // for 32-byte key and 16-byte iv
    {
        preHashLength = currentHash.Length + data.Length + ((salt != null) ? salt.Length : 0);
        preHash = new byte[preHashLength];

        System.Buffer.BlockCopy(currentHash, 0, preHash, 0, currentHash.Length);
        System.Buffer.BlockCopy(data, 0, preHash, currentHash.Length, data.Length);
        if (salt != null)
            System.Buffer.BlockCopy(salt, 0, preHash, currentHash.Length + data.Length, salt.Length);

        currentHash = hash.ComputeHash(preHash);            

        for (int i = 1; i < count; i++)
        {
            currentHash = hash.ComputeHash(currentHash);
        }

        hashList.AddRange(currentHash);
    }
    hash.Clear();
    key = new byte[32];
    iv = new byte[16];
    hashList.CopyTo(0, key, 0, 32);
    hashList.CopyTo(32, iv, 0, 16);
}