如何解决不支持单声道的异常调用CryptDeriveKey CspParameters [英] how to fix CspParameters not supported by Mono exception calling CryptDeriveKey

查看:144
本文介绍了如何解决不支持单声道的异常调用CryptDeriveKey CspParameters的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试端口ASP .NET MVC2密码恢复code从<一个href="http://stackoverflow.com/questions/7793108/where-to-find-c-sharp-sample-$c$c-to-implement-password-recovery-in-asp-net-mvc">Where找到C#示例code来实现密码恢复在ASP .NET MVC2 回答单。 我它包含以下步骤。 CryptDeriveKey呼叫单导致异常

  CspParameters不支持单声道
 

如何实现恢复密码单在ASP .NET MVC2应用程序?

  ///&LT;总结&gt;
    ///将一个文本消息并使用密码作为密钥加密。
    ///&LT; /总结&gt;
    ///&LT; PARAM NAME =plainMessage&GT; A文本加密&LT; /参数&GT;
    ///&LT; PARAM NAME =密码&gt;到的信息进行加密的密码&LT; /参数&GT;
    ///&LT;返回&GT;加密字符串&LT; /回报&GT;
    ///&LT;说明&GT;此方法使用了TripleDes symmmectric加密&LT; /说明&GT;
    公共静态字符串连接codeMessageWithPassword(字符串plainMessage,串密码)
    {
        如果(plainMessage == NULL)
            抛出新ArgumentNullException(encryptedMessage,该消息不能为空);

        TripleDESCryptoServiceProvider DES =新TripleDESCryptoServiceProvider();
        des.IV =新的字节[8]。

        //创建基于所述口令并将其存储在一个字节数组的关键。
        PasswordDeriveBytes PDB =新PasswordDeriveBytes(密码,新的字节[0]);
        //单声道CryptDeriveKey导致异常:
        //不支持单声道CspParameters
        des.Key = pdb.CryptDeriveKey(RC2,MD5,128,新的字节[8]);

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

        返回Convert.ToBase64String(encryptedBytes);
    }
 

解决方案

您不能的修正的这种作为类型 CspParameters 不是的真正的支持单声道。

的原因是,这种类型的用于之间的(管理)BCL code和中的CryptoAPI的CSP(加密服务提供者)进行通信的额外信息。由于单只使用管理code和CryptoAPI的不可用的Windows之外则 CspParameters 类主要是存根,没有code的定义。

在特定类型的<一个href="http://kipunji.jpobst.com/kipunji/mscorlib.dll/System.Security.Cryptography.PasswordDeriveBytes"相对=nofollow> PasswordDeriveBytes 是有点特殊。它实现了标准PKCS#5 1.5版,该单声道支持,但它也增加了一些微软的扩展(打破了规范)其中一个其中一人是完全 打破(安全明智的)。你应该在使用 PasswordDeriveBytes 特别小心。<​​/ P>

该案例 CryptDeriveKey 更是设计很差。它无关的(任何版本)PKCS#5,如 PasswordDeriveBytes 的其余部分(即它不是基于标准的)。它的作用是简单地使用默认的CSP重定向参数以CryptoAPI的。有些专业的学生出现问题时形成的:

  1. AFAIK微软从未公布的算法(),他们正在使用的推导的及其的CSP键。我不能说,如果它甚至安全的,他们的PKCS#5的扩展不是;

  2. 默认CSP可以更改(例如,通过应用程序),默认为一个非微软的CSP(如hardward /智能卡CSP)。这些CSP提供的密钥派生算法是未知的(希望他们回调到MS CSP);

  3. 的CryptoAPI和CSP仅适用于Windows和相差Windows版本/出口能力,在.NET框架没有的版本。

您应该避免使用 PasswordDeriveBytes.CryptDeriveKey ,即使在Windows,除非你能保证默认CSP是(并将继续)在整个运行应用程序的所有计算机相同的。

总之,为了避免互操作性/​​安全问题,我强烈建议您使用较新的PKCS#5 V2,其中单声道/ MonoTouch的/微软实现为 System.Security.Cryptography.Rfc2898DeriveBytes

I try to port ASP .NET MVC2 password recovery code from Where to find C# sample code to implement password recovery in ASP .NET MVC2 answer to Mono. I it contains procedure below. CryptDeriveKey call causes exception in Mono

CspParameters not supported by Mono

How to implement password recovery in Mono in ASP .NET MVC2 application ?

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

解决方案

You cannot fix this as the type CspParameters is not really supported by Mono.

The reason is that this type is used to communicate extra information between the (managed) BCL code and the CryptoAPI's CSP (crypto service provider). Since Mono use only managed code and that CryptoAPI is not available outside Windows then the CspParameters class is mostly a stub, a definition without code.

In particular the type PasswordDeriveBytes is a bit special. It implements the standard PKCS#5 v1.5, which Mono supports, but it also adds a few Microsoft extensions (breaking the specification) including one one them being totally broken (security wise). You should take great care when using PasswordDeriveBytes.

The case for CryptDeriveKey is even more badly designed. It has nothing to do with (any version of) PKCS#5, like the rest of PasswordDeriveBytes (i.e. it's not standard-based). What it does is simply redirect your parameters to CryptoAPI using the default CSP. Some majors issues arise form this:

  1. AFAIK Microsoft never published the algorithm(s) they are using to derive keys in their CSP. I can't say if it's even secure, their PKCS#5 extensions were not;

  2. The "default" CSP can be changed (e.g. by applications) to default to a non-Microsoft CSP (e.g. hardward/smartcard CSP). The key derivation algorithm provided by those CSP is unknown (hopefully they call back into MS CSP);

  3. CryptoAPI and the CSP are only available on Windows and differs by the version of Windows/exportability, not the version of the .NET framework.

You should avoid using PasswordDeriveBytes.CryptDeriveKey, even on Windows, unless you can assure the default CSP is (and will remain) identical across all computers running your application.

In conclusion, to avoid interoperability / security issues, I strongly suggest your to use the newer PKCS#5 v2, which Mono/MonoTouch/Microsoft implements as System.Security.Cryptography.Rfc2898DeriveBytes.

这篇关于如何解决不支持单声道的异常调用CryptDeriveKey CspParameters的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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