OpenSSL的C#版本EVP_BytesToKey方法?

我正在寻找OpenSSL EVP_BytesToKey函数的直接.NET实现。我找到的最接近的东西是System.Security.Cryptography.PasswordDeriveBytes类(和Rfc2898DeriveBytes),但它似乎略有不同,并且不会生成与EVP_BytesToKey 相同的键和iv。


我还发现此实现似乎是一个不错的开始,但没有考虑迭代计数。


我意识到这里有OpenSSL.NET,但这只是本机openssl DLL的包装,而不是“真正的” .NET实现。


叮当猫咪
浏览 719回答 1
1回答

蝴蝶不菲

我找到了EVP_BytesToKey方法的伪代码说明(在openssl源代码的/doc/ssleay.txt中):/* M[] is an array of message digests&nbsp;* MD() is the message digest function */M[0]=MD(data . salt);for (i=1; i<count; i++) M[0]=MD(M[0]);i=1while (data still needed for key and iv)&nbsp; &nbsp; {&nbsp; &nbsp; M[i]=MD(M[i-1] . data . salt);&nbsp; &nbsp; for (i=1; i<count; i++) M[i]=MD(M[i]);&nbsp; &nbsp; i++;&nbsp; &nbsp; }If the salt is NULL, it is not used.The digests are concatenated together.M = M[0] . M[1] . M[2] .......因此,基于此,我能够提出这种C#方法(该方法似乎可以满足我的目的,并假定使用32字节的密钥和16字节的iv):private static void DeriveKeyAndIV(byte[] data, byte[] salt, int count, out byte[] key, out byte[] iv){&nbsp; &nbsp; List<byte> hashList = new List<byte>();&nbsp; &nbsp; byte[] currentHash = new byte[0];&nbsp; &nbsp; int preHashLength = data.Length + ((salt != null) ? salt.Length : 0);&nbsp; &nbsp; byte[] preHash = new byte[preHashLength];&nbsp; &nbsp; System.Buffer.BlockCopy(data, 0, preHash, 0, data.Length);&nbsp; &nbsp; if (salt != null)&nbsp; &nbsp; &nbsp; &nbsp; System.Buffer.BlockCopy(salt, 0, preHash, data.Length, salt.Length);&nbsp; &nbsp; MD5 hash = MD5.Create();&nbsp; &nbsp; currentHash = hash.ComputeHash(preHash);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; for (int i = 1; i < count; i++)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; currentHash = hash.ComputeHash(currentHash);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; hashList.AddRange(currentHash);&nbsp; &nbsp; while (hashList.Count < 48) // for 32-byte key and 16-byte iv&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; preHashLength = currentHash.Length + data.Length + ((salt != null) ? salt.Length : 0);&nbsp; &nbsp; &nbsp; &nbsp; preHash = new byte[preHashLength];&nbsp; &nbsp; &nbsp; &nbsp; System.Buffer.BlockCopy(currentHash, 0, preHash, 0, currentHash.Length);&nbsp; &nbsp; &nbsp; &nbsp; System.Buffer.BlockCopy(data, 0, preHash, currentHash.Length, data.Length);&nbsp; &nbsp; &nbsp; &nbsp; if (salt != null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.Buffer.BlockCopy(salt, 0, preHash, currentHash.Length + data.Length, salt.Length);&nbsp; &nbsp; &nbsp; &nbsp; currentHash = hash.ComputeHash(preHash);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 1; i < count; i++)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currentHash = hash.ComputeHash(currentHash);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; hashList.AddRange(currentHash);&nbsp; &nbsp; }&nbsp; &nbsp; hash.Clear();&nbsp; &nbsp; key = new byte[32];&nbsp; &nbsp; iv = new byte[16];&nbsp; &nbsp; hashList.CopyTo(0, key, 0, 32);&nbsp; &nbsp; hashList.CopyTo(32, iv, 0, 16);}更新:这里更多/更少相同的实现,但是使用.NET DeriveBytes接口:https ://gist.github.com/1339719OpenSSL 1.1.0c更改了某些内部组件中使用的摘要算法。以前使用MD5,并且1.1.0切换到SHA256。小心的变化不影响你在这两个EVP_BytesToKey和命令一样openssl enc。
打开App,查看更多内容
随时随地看视频慕课网APP