如何修复调用 CryptDeriveKey 的 Mono 异常不支持的 CspParameters [英] how to fix CspParameters not supported by Mono exception calling CryptDeriveKey

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

问题描述

我尝试从 在哪里可以找到 C# 示例代码以在 ASP .NET MVC2 中实现密码恢复 对 Mono 的回答.我它包含以下程序.CryptDeriveKey 调用导致 Mono 中的异常

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

如何在 ASP .NET MVC2 应用程序中实现 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);
    }

推荐答案

你不能修复因为类型 CspParameters 不支持真正单声道.

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

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

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.

尤其是类型 PasswordDeriveBytes 有点特别.它实现了 Mono 支持的标准 PKCS#5 v1.5,但它还添加了一些 Microsoft 扩展(违反规范)包括一个完全a> 损坏(安全方面).使用 PasswordDeriveBytes 时应格外小心.

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.

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

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 从未发布他们用来在他们的 CSP 中派生密钥的算法.我不能说它是否安全,他们的 PKCS#5 扩展不安全;

  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;

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

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

CryptoAPI 和 CSP 仅在 Windows 上可用,并且因 Windows/exportability 的版本而异,而不是 .NET 框架的版本.

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

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

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.

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

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 的 Mono 异常不支持的 CspParameters的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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