Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何修复调用CryptDeriveKey的Mono异常不支持的CSP参数_C#_.net_Mono_Cryptography_Security - Fatal编程技术网

C# 如何修复调用CryptDeriveKey的Mono异常不支持的CSP参数

C# 如何修复调用CryptDeriveKey的Mono异常不支持的CSP参数,c#,.net,mono,cryptography,security,C#,.net,Mono,Cryptography,Security,我尝试将ASP.NETMVC2密码恢复代码从answer移植到Mono。 它包含以下步骤。CryptDeriveKey调用在Mono中导致异常 CspParameters not supported by Mono 如何在ASP.NETMVC2应用程序中实现Mono中的密码恢复 /// <summary> /// Takes a text message and encrypts it using a password as a key. /// <

我尝试将ASP.NETMVC2密码恢复代码从answer移植到Mono。 它包含以下步骤。CryptDeriveKey调用在Mono中导致异常

CspParameters not supported by Mono
如何在ASP.NETMVC2应用程序中实现Mono中的密码恢复

    /// <summary> 
    /// Takes a text message and encrypts it using a password as a key. 
    /// </summary> 
    /// <param name="plainMessage">A text to encrypt.</param> 
    /// <param name="password">The password to encrypt the message with.</param> 
    /// <returns>Encrypted string.</returns> 
    /// <remarks>This method uses TripleDES symmmectric encryption.</remarks> 
    public static string EncodeMessageWithPassword(string plainMessage, string password)
    {
        if (plainMessage == null)
            throw new ArgumentNullException("encryptedMessage", "The message cannot be null");

        TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
        des.IV = new byte[8];

        //Creates the key based on the password and stores it in a byte array. 
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, new byte[0]);
        // in mono CryptDeriveKey causes exception:
        // CspParameters not supported by Mono
        des.Key = pdb.CryptDeriveKey("RC2", "MD5", 128, new byte[8]);

        MemoryStream ms = new MemoryStream(plainMessage.Length * 2);
        CryptoStream encStream = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
        byte[] plainBytes = Encoding.UTF8.GetBytes(plainMessage);
        encStream.Write(plainBytes, 0, plainBytes.Length);
        encStream.FlushFinalBlock();
        byte[] encryptedBytes = new byte[ms.Length];
        ms.Position = 0;
        ms.Read(encryptedBytes, 0, (int)ms.Length);
        encStream.Close();

        return Convert.ToBase64String(encryptedBytes);
    }
//
///接收文本消息并使用密码作为密钥对其进行加密。
///  
///要加密的文本。
///用于加密消息的密码。
///加密字符串。
///此方法使用三重对称加密。
公共静态字符串EncodeMessageWithPassword(字符串明文消息,字符串密码)
{
if(明文==null)
抛出新ArgumentNullException(“encryptedMessage”,“消息不能为null”);
TripleDESCryptoServiceProvider des=新的TripleDESCryptoServiceProvider();
des.IV=新字节[8];
//基于密码创建密钥并将其存储在字节数组中。
PasswordDeriveBytes pdb=新PasswordDeriveBytes(密码,新字节[0]);
//在mono CryptDeriveKey中,会导致异常:
//Mono不支持CSP参数
des.Key=pdb.CryptDeriveKey(“RC2”,“MD5”,128,新字节[8]);
MemoryStream ms=新的MemoryStream(plainMessage.Length*2);
CryptoStream encStream=新加密流(ms,des.CreateEncryptor(),CryptoStreamMode.Write);
byte[]plainBytes=Encoding.UTF8.GetBytes(plainMessage);
encStream.Write(纯字节,0,纯字节.Length);
encStream.FlushFinalBlock();
字节[]encryptedBytes=新字节[ms.Length];
ms.Position=0;
ms.Read(encryptedBytes,0,(int)ms.Length);
encStream.Close();
返回Convert.tobase64字符串(encryptedBytes);
}
您无法修复此问题,因为Mono并不真正支持类型
CspParameters

原因是该类型用于在(托管)BCL代码和CryptoAPI的CSP(加密服务提供商)之间传输额外信息。由于Mono只使用托管代码,并且CryptoAPI在Windows之外不可用,因此
CspParameters
类主要是一个存根,一个没有代码的定义

特别是类型有点特殊。它实现了Mono支持的标准PKCS#5 v1.5,但它还添加了一些Microsoft(违反规范),其中一个是(安全方面的)。使用
PasswordDeriveBytes
时应格外小心

CryptDeriveKey
的情况设计得更糟糕。它与PKCS#5的(任何版本)无关,就像其他的
PasswordDeriveBytes
(即,它不是基于标准的)。它所做的只是使用默认CSP将参数重定向到CryptoAPI。由此产生了一些主要问题:

  • AFAIK Microsoft从未发布他们用于在CSP中导出密钥的算法。我不能说它是否安全,他们的PKCS#5扩展不安全

  • 可以将“默认”CSP(例如,通过应用程序)更改为默认为非Microsoft CSP(例如,硬卡/智能卡CSP)。这些CSP提供的密钥派生算法是未知的(希望他们能调用MS CSP)

  • CryptoAPI和CSP仅在Windows上可用,不同之处在于Windows/Exportable的版本,而不是.NET framework的版本

  • 即使在Windows上,您也应该避免使用
    PasswordDeriveBytes.CryptDeriveKey
    ,除非您可以确保运行应用程序的所有计算机上的默认CSP都是(并且将保持)相同的


    总之,为了避免互操作性/安全问题,我强烈建议您使用更新的PKCS#5 v2,Mono/MonoTouch/Microsoft将其实现为。

    非常感谢。我将此方法中的两行更改为
    var pdb=new Rfc2898DeriveBytes(密码,new byte[8]);des.Key=pdb.GetBytes(16)。这是最好的解决方案吗?是的,这很好-但您可能需要硬编码一些其他值(而不是空的
    字节
    数组)。