【问题标题】:Decrypt an encrypted text解密加密文本
【发布时间】:2015-06-12 16:25:49
【问题描述】:

我在我的 Windows 窗体应用程序中有一个文本框和一个“解密”按钮,我在其中放置了一个加密字符串并尝试对其进行解密,但问题是这样的。首先,我从这个网站上的一个人那里得到了这个名为 DataEncryptor 的课程代码:

public class DataEncryptor
{
    TripleDESCryptoServiceProvider symm;

    #region Factory
    public DataEncryptor()
    {
        this.symm = new TripleDESCryptoServiceProvider();
        this.symm.Padding = PaddingMode.PKCS7;
    }
    public DataEncryptor(TripleDESCryptoServiceProvider keys)
    {
        this.symm = keys;
    }

    public DataEncryptor(byte[] key, byte[] iv)
    {
        this.symm = new TripleDESCryptoServiceProvider();
        this.symm.Padding = PaddingMode.PKCS7;
        this.symm.Key = key;
        this.symm.IV = iv;
    }

    #endregion

    #region Properties
    public TripleDESCryptoServiceProvider Algorithm
    {
        get { return symm; }
        set { symm = value; }
    }
    public byte[] Key
    {
        get { return symm.Key; }
        set { symm.Key = value; }
    }
    public byte[] IV
    {
        get { return symm.IV; }
        set { symm.IV = value; }
    }

    #endregion

    #region Crypto

    public byte[] Encrypt(byte[] data) { return Encrypt(data, data.Length); }
    public byte[] Encrypt(byte[] data, int length)
    {
        try
        {
            // Create a MemoryStream.
            var ms = new MemoryStream();

            // Create a CryptoStream using the MemoryStream 
            // and the passed key and initialization vector (IV).
            var cs = new CryptoStream(ms,
                symm.CreateEncryptor(symm.Key, symm.IV),
                CryptoStreamMode.Write);

            // Write the byte array to the crypto stream and flush it.
            cs.Write(data, 0, length);
            cs.FlushFinalBlock();

            // Get an array of bytes from the 
            // MemoryStream that holds the 
            // encrypted data.
            byte[] ret = ms.ToArray();

            // Close the streams.
            cs.Close();
            ms.Close();

            // Return the encrypted buffer.
            return ret;
        }
        catch (CryptographicException ex)
        {
            Console.WriteLine("A cryptographic error occured: {0}", ex.Message);
        }
        return null;
    }

    public string EncryptString(string text)
    {
        return Convert.ToBase64String(Encrypt(Encoding.UTF8.GetBytes(text)));
    }

    public byte[] Decrypt(byte[] data) { return Decrypt(data, data.Length); }
    public byte[] Decrypt(byte[] data, int length)
    {
        try
        {
            // Create a new MemoryStream using the passed 
            // array of encrypted data.
            MemoryStream ms = new MemoryStream(data);

            // Create a CryptoStream using the MemoryStream 
            // and the passed key and initialization vector (IV).
            CryptoStream cs = new CryptoStream(ms,
                symm.CreateDecryptor(symm.Key, symm.IV),
                CryptoStreamMode.Read);

            // Create buffer to hold the decrypted data.
            byte[] result = new byte[length];

            // Read the decrypted data out of the crypto stream
            // and place it into the temporary buffer.
            cs.Read(result, 0, result.Length);
            return result;
        }
        catch (CryptographicException ex)
        {
            Console.WriteLine("A cryptographic error occured: {0}", ex.Message);
        }
        return null;
    }

    public string DecryptString(string data)
    {
        return Encoding.UTF8.GetString(Decrypt(Convert.FromBase64String(data))).TrimEnd('\0');
    }

    #endregion

}

他给出了它的用法:

string message="A very secret message here.";
DataEncryptor keys=new DataEncryptor();
string encr=keys.EncryptString(message);

// later
string actual=keys.DecryptString(encr);

我复制了他的代码并从事加密和解密工作:

//my code
private void proceedED(string data)
{
    DataEncryptor key = new DataEncryptor();
    string encr = key.EncryptString(data);
    string actual = key.DecryptString(encr);
    encryptedLabel.Text = encr;
    decryptedLabel.Text = actual;     
}

然后我创建了一个这样的方法:

private void proceedDecrypt(string data) 
{
    DataEncryptor key = new DataEncryptor();
    string decr = key.DecryptString(data);
    decryptedData.Text = decr;
}

问题是我提交时它崩溃了,我不知道为什么。 我认为它应该是一个真正的加密字符串,因为它只是一个普通的字符串。 我该如何解决这个问题?

【问题讨论】:

  • 它给出了什么例外?在所有关于“错误”、“崩溃”等的帖子中都包含异常的消息和堆栈跟踪?也许,您还没有初始化密钥或者您的data 有问题。如果没有异常消息,我们无法知道它。
  • Array cannot be null Paramater name: bytes 行错误在 DataEncryptor 类底部的 DecryptString(string data) 方法中
  • 看起来您创建了方法proceedDecrypt,但将空的data 传递给它。看你调用这个方法的地方。
  • 我认为它需要是一个真正的加密字符串,因为它只是一个普通的字符串
  • 嗯,这段代码对我来说很熟悉。见stackoverflow.com/a/10176980/380384

标签: c# encryption


【解决方案1】:

DataEncryptor 的每个实例都会生成新的密钥。您需要使用加密字符串的相同密钥进行解密。如果这是在同一进程中完成的,则保留对 DataEncryptor key 的引用。否则需要使用DataEncryptor(byte[] key, byte[] iv) 构造函数进行初始化。

试试这样的代码:

class Program
{
    static void Main(string[] args)
    {
        string key, iv;

        var plain="A very secret message.";
        var cipher=EncryptString(plain, out key, out iv);

        // Later ...

        var message=DecryptString(cipher, key, iv);
    }

    public static string EncryptString(string plain, out string key, out string iv)
    {
        var crypto=new DataEncryptor();
        iv=Convert.ToBase64String(crypto.IV);
        key=Convert.ToBase64String(crypto.Key);
        return crypto.EncryptString(plain);
    }

    public static string DecryptString(string cipher, string key, string iv)
    {
        var crypto=new DataEncryptor(
            Convert.FromBase64String(key), 
            Convert.FromBase64String(iv));

        return crypto.DecryptString(cipher);
    }
}

【讨论】:

    【解决方案2】:

    您可以通过 System.Security.Cryptography 使用加密和解密

    1) Set encryption decription key
    2) Encrypt data with encryption key
    3) Decrypt data with same encryption key
    

    请参阅下面的加密和解密示例链接。 Encryption/Decryption Function in .NET using the TripleDESCryptoServiceProvider Class

    【讨论】:

      【解决方案3】:

      您正在两个函数中创建新对象;

      DataEncryptor key = new DataEncryptor();
      

      这就是你的错误的原因。

      只要声明;

         DataEncryptor key = new DataEncryptor();
      

      在您的proceedED() 和proceedDecrypt() 之外,我的意思是公开它。

      或者您可以将密钥作为参数传递给proceedDecrypt()并在该函数中使用它。

      喜欢;

      DataEncryptor key = new DataEncryptor();
      
      private void proceedED(string data)
      {
        string encr = key.EncryptString(data);
        string actual = key.DecryptString(encr);
        encryptedLabel.Text = encr;
        decryptedLabel.Text = actual; 
        proceedDecrypt(encr);    
      }
      
      private void proceedDecrypt(string data) 
      {
      
          string decr = key.DecryptString(data);
          decryptedData.Text = decr;
      }
      

      希望对你有帮助..!!!

      【讨论】:

      • 检查编辑,如果有错误,请告诉我你得到了什么错误......!!!还有你是如何调用proceedDecrypt()函数的?
      【解决方案4】:

      好吧,我终于解决了……

      我从https://social.msdn.microsoft.com/Forums/vstudio/en-US/d6a2836a-d587-4068-8630-94f4fb2a2aeb/encrypt-and-decrypt-a-string-in-c?forum=csharpgeneral复制了这段代码

          static readonly string PasswordHash = "P@@Sw0rd";
          static readonly string SaltKey = "S@LT&KEY";
          static readonly string VIKey = "@1B2c3D4e5F6g7H8";
      
          public static string Encrypt(string plainText)
          {
              byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
      
              byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
              var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };
              var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
      
              byte[] cipherTextBytes;
      
              using (var memoryStream = new MemoryStream())
              {
                  using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                  {
                      cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                      cryptoStream.FlushFinalBlock();
                      cipherTextBytes = memoryStream.ToArray();
                      cryptoStream.Close();
                  }
                  memoryStream.Close();
              }
              return Convert.ToBase64String(cipherTextBytes);
          }
          public static string Decrypt(string encryptedText)
          {
              byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);
              byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
              var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };
      
              var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
              var memoryStream = new MemoryStream(cipherTextBytes);
              var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
              byte[] plainTextBytes = new byte[cipherTextBytes.Length];
      
              int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
              memoryStream.Close();
              cryptoStream.Close();
              return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("\0".ToCharArray());
          }
      

      并删除了DataEncryptor

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-24
        • 1970-01-01
        • 2015-03-26
        • 1970-01-01
        • 2017-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多