System.Security.Cryptography и «Bad Data» - кодировка символов? - PullRequest
1 голос
/ 19 марта 2009

Класс, который выдает ошибки "Bad Data":


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?

Кажется, у меня где-то есть ссылка, но я расстраиваюсь, поэтому я подумал, что по крайней мере это поможет, если я перестану делать что-то кроме чтения и компиляции ...

Кстати, я звоню этому классу, чтобы записать пароль в файл XML с использованием инфраструктуры инициализации Nini. http://nini.sourceforge.net/manual.php#ASimpleExample

Кроме того, я использовал Notepad2 для изменения кодировки файла (UTF-8) до того, как записал в файл XML.

Это было после того, как программа остановилась после того, как я скомпилировал первый раз. Используя отладчик, я смог увидеть, что кодировка XML-данных в памяти (UTF-8) и данных на диске (ANSI) была разной.

Похоже, что сейчас это не так, но программа по-прежнему останавливается, ссылаясь на неверные данные, возвращенные из части Decrypt RSAcrypt ().

(также обратите внимание, что Encrypt и Decrypt были идентичными методами до того, как началось мое разочарование, они функционируют одинаково, но я хотел попытаться получить дополнительную информацию об исключениях, связанных с заявкой о неверных данных. Конечно, вы заметите, что я позволил моему разочарованию помешать моему коду ;-))

Любые предложения, идеи или ссылки будут великолепны.

ТИА

E

1 Ответ

3 голосов
/ 19 марта 2009

Внутри вашего конструктора вы генерируете новую пару ключей RSA каждый раз, когда делаете:

   RSACryptoServiceProvider thisRSACryptoServiceProvider = new RSACryptoServiceProvider();

Поскольку ваш конструктор - это то место, где вы шифруете и дешифруете, вы шифруете с помощью ключа RSA, а дешифруете совершенно другим.

Чтобы сделать это, у вас есть несколько вариантов, основанных на том, как вы планируете использовать свой код.

Один из вариантов - экспортировать ключ RSA и использовать его для всех операций шифрования / дешифрования. Это единственный вариант, если вы планируете расшифровывать / шифровать данные между различными запусками исполняемого файла.

Конечно, это полностью скрывает, как вы будете хранить ваш открытый / закрытый ключ (я рекомендую DPAPI в Windows) для использования вашим приложением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...