CryptDeriveKey失败AES算法名算法、CryptDeriveKey、AES

2023-09-03 04:40:45 作者:窒息.

我想实现的AES加密在我的应用程序。我有以下的code创建的用户密码哈希版本。

I'm trying to implement AES encryption in my application. I have the following code to create a hashed version of the user password.

PasswordDeriveBytes passwdHash = new PasswordDeriveBytes( password, salt, 
                                                          "SHA1", 128 );
byte[] keyBytes                = passwdHash.CryptDeriveKey( "AES", "SHA1", 
                                                            192, iv );

第二行抛出一个 System.Security.Cryptography.CryptographicException 的错误信息对象标识符(OID)是未知。我使用反射来验证被抛出的错误,因为 CryptDeriveKey()不喜欢AES算法名(我使用 AesCryptoServiceProvider( )来执行加密)。我试图改变名称为AESManaged,AES192和Rijndael算法,但他们都抛出同样的异常。

The second line throws a System.Security.Cryptography.CryptographicException with the error message Object identifier (OID) is unknown. I used Reflector to verify that the error is being thrown because CryptDeriveKey() does not like the "AES" algorithm name (I'm using AesCryptoServiceProvider() to perform the encryption). I tried changing the name to "AESManaged", "AES192" and "Rijndael" but they all throw the same exception.

我如何得到这个工作?或者是有导出密钥字节的替代方法? 此外,有没有在允许的算法名字符串是什么样的任何文件?我找不到MSDN文档该函数的任何信息。

How do I get this to work? Or is there an alternative method of deriving the key bytes? Also, is there any documentation on what the allowed algorithm name strings are? I can't find anything on the MSDN docs for that function.

我使用Visual Studio 2008和目标.NET Framework 3.5的

I'm using Visual Studio 2008 and target .NET framework 3.5

在此先感谢您的帮助!

推荐答案

为什么要来源于密码盐,而不是密码本身的关键?通常你用原始的密码和盐;确实是在我的书(的笑容的)第6章有以下示例。

Why do you want to derive a key from a password salt rather than the password itself? Usually you use the "raw" password and a salt; indeed in my book (grin) chapter 6 has the following sample.

private void GetKeyAndIVFromPasswordAndSalt(
    string password, 
    byte[] salt, 
    SymmetricAlgorithm symmetricAlgorithm, 
    ref byte[] key, 
    ref byte[] iv)
{
    Rfc2898DeriveBytes rfc2898DeriveBytes = 
        new Rfc2898DeriveBytes(password, salt);
    key = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.KeySize / 8);
    iv =  rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.BlockSize / 8); 
}

当然盐应该是一个加密的安全随机字节数组;

Of course salt should be a cryptographically secure random byte array;

private static byte[] GenerateKeyGenerateRandomBytes(int length)
{
    byte[] key = new byte[length];
    RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
    provider.GetBytes(key);
    return key;
}