System.Security.Cryptography和“Bad Data” - 字符编码?

时间:2009-03-19 19:48:06

标签: c# xml encryption

产生“错误数据”错误的类:


using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;

namespace MyNameSpace
{

  public class RSAcrypt
  {
    private string _encryptedData;
    private string _decryptedData;

    public string EncryptedData
    {
      get { return _encryptedData; }
      set { _encryptedData  = value; }
    }

    public string DecryptedData
    {
      get { return _decryptedData; }
      set { _decryptedData  = value; }
    }

    public RSAcrypt()
    {
    }
    /// <param name="CryptAction"> The action to perform on the string {Encrypt|Decrypt} </param >
    /// <param name="StringToCrypt"> A string to perform the Action on </param>
    public RSAcrypt(string CryptAction, string StringToCrypt)
    {
        UnicodeEncoding thisUnicodeEncoding = new UnicodeEncoding();
        RSACryptoServiceProvider thisRSACryptoServiceProvider = new RSACryptoServiceProvider();
        byte[] _stringToCrypt = thisUnicodeEncoding.GetBytes(StringToCrypt);

        switch (CryptAction)
        {
            case "Encrypt":
                byte[] encryptedData = Encrypt(_stringToCrypt, thisRSACryptoServiceProvider.ExportParameters(false));
                _encryptedData = thisUnicodeEncoding.GetString(encryptedData);
            break;

            case "Decrypt":
                byte[] decryptedData = Decrypt(_stringToCrypt, thisRSACryptoServiceProvider.ExportParameters(true));
                _decryptedData = thisUnicodeEncoding.GetString(decryptedData);
            break;

            default:

            break;
        }

    }

    static private byte[] Encrypt(byte[] DataToEncrypt, RSAParameters keyInfo)
    {
        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
        RSA.ImportParameters(keyInfo);
        return RSA.Encrypt(DataToEncrypt, false);
    }

    static private byte[] Decrypt(byte[] DataToDecrypt, RSAParameters keyInfo)
    {
      #region Temporary Assignment - Remove before build

      byte[] tmpVal = null;

      #endregion

      RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

      try
      {
          RSA.ImportParameters(keyInfo);

          #region Temporary Assignment - Remove before build

          tmpVal = RSA.Decrypt(DataToDecrypt, false);

          #endregion
      }
      catch (Exception ex)
      {

          MessageBox.Show("Error: " + ex.Message, "Exception Thrown");

      }

      #region Temporary Assignment - Remove before build

      return tmpVal;

      #endregion
    }
  }
}

有什么我可以在这个类中更改,允许我在将字节数组传递给Encrypt / Decrypt之前检查编码吗?

好像我在这里有一个参考,但是我变得很沮丧,所以我认为如果我停下来做除了阅读和编译之外的其他事情,这至少会有所帮助......

BTW,我正在调用此类,使用Nini初始化框架将密码写入XML文件。 http://nini.sourceforge.net/manual.php#ASimpleExample

另外,在写入XML文件之前,我使用Notepad2来更改文件编码(UTF-8)。

这是在我第一次编译后程序停止之后。使用调试器,我能够看到内存中的XML数据(UTF-8)和磁盘上的数据(ANSI)之间的编码不同。

现在似乎并非如此,但程序仍然停止,引用从RSAcrypt()的Decrypt部分返回的错误数据。

(另请注意,加密和解密是相同的方法,在我的挫折设置之前,它们的功能相同,但我想尝试捕获与坏数据声明相关的额外异常信息。当然,你会注意到我允许我的挫败感妨碍我的代码;-))

任何建议,想法或参考都会很棒。

TIA,

电子

1 个答案:

答案 0 :(得分:3)

在构造函数中,每次执行时都会生成一个新的RSA密钥对:

   RSACryptoServiceProvider thisRSACryptoServiceProvider = new RSACryptoServiceProvider();

由于您的构造函数是加密和解密的地方,因此您使用RSA密钥进行加密,并使用完全不同的密钥进行解密。

为了完成这项工作,您可以根据计划使用代码的方式选择几种方法。

一种选择是导出RSA密钥,并将其用于所有加密/解密操作。如果您计划在不同的可执行文件运行之间解密/加密数据,这是唯一的选择。

当然,这完全掩盖了如何存储您的公钥/私钥(我建议在Windows上使用DPAPI),供您的应用程序使用。