【问题标题】:How to Decrypt an Encrypted String using a specific Key如何使用特定密钥解密加密字符串
【发布时间】:2016-02-10 12:46:25
【问题描述】:

首先这是我目前的代码。

public Form1()
{
    InitializeComponent();
    desObj = Rijndael.Create();
}

string cData;
byte[] cBytes;
byte[] pBytes;
byte[] pBytes2;
byte[] pKey;
SymmetricAlgorithm desObj;

public static string InputBox(string title, string promptText)
{
    Form form = new Form();
    Label label = new Label();
    TextBox textBox = new TextBox();
    Button buttonOk = new Button();
    Button buttonCancel = new Button();

    form.Text = title;
    label.Text = promptText;

    buttonOk.Text = "OK";
    buttonCancel.Text = "Cancel";
    buttonOk.DialogResult = DialogResult.OK;
    buttonCancel.DialogResult = DialogResult.Cancel;

    label.SetBounds(9, 20, 372, 13);
    textBox.SetBounds(12, 36, 372, 20);
    buttonOk.SetBounds(228, 72, 75, 23);
    buttonCancel.SetBounds(309, 72, 75, 23);

    label.AutoSize = true;

    textBox.MaxLength = 16;
    textBox.Anchor = textBox.Anchor | AnchorStyles.Right;
    buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
    buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;

    form.ClientSize = new Size(396, 107);
    form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel });
    form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
    form.FormBorderStyle = FormBorderStyle.FixedDialog;
    form.StartPosition = FormStartPosition.CenterScreen;
    form.MinimizeBox = false;
    form.MaximizeBox = false;
    form.AcceptButton = buttonOk;
    form.CancelButton = buttonCancel;
    DialogResult dR = form.ShowDialog();
    string test = textBox.Text;
    MessageBox.Show("test: "+test);
    if (test.Length != 16)
    {
        int pKey2NeededLength = 0;
        for (int i = 0; i < (test.Length + 16); i++)
        {
            if ((i + test.Length) == 16)
            {
                pKey2NeededLength = i;
                MessageBox.Show("pKey2NeededLength: "+pKey2NeededLength);
                break;
            }
        }
        StringBuilder sB = new StringBuilder();
        string[] pArray = { "1", "12", "123", "1234", "12345", "123456", "1234567", "12345678", "123456789", "1234567891", "12345678912", "123456789123", "1234567891234", "12345678912345", "123456789123456", "1234567891234567" };
        sB.Append(test + pArray[pKey2NeededLength - 1]);
        test = sB.ToString();
        MessageBox.Show("test(after sB): "+test);
    }
    return test;
}

private void button1_Click(object sender, EventArgs e)//ENCRYPT
{
    cData = richTextBox1.Text;
    pBytes = Encoding.ASCII.GetBytes(cData);
    string pKey2 = InputBox("Encryption-Key", "Enter a Encryption-Key:");
    pKey = Encoding.ASCII.GetBytes(pKey2);
    desObj.Key = pKey;
    desObj.Mode = CipherMode.CBC;
    desObj.Padding = PaddingMode.PKCS7;
    System.IO.MemoryStream mS = new System.IO.MemoryStream();
    CryptoStream cS = new CryptoStream(mS, desObj.CreateEncryptor(), CryptoStreamMode.Write);
    cS.Write(pBytes, 0, pBytes.Length);
    cS.Close();
    cBytes = mS.ToArray();
    mS.Close();
    richTextBox1.Text = Encoding.ASCII.GetString(cBytes);
}

private void button2_Click(object sender, EventArgs e)//DECRYPT
{
    string pKey3 = InputBox("Decryption-Key", "Enter a Decryption-Key:");
    MessageBox.Show("pKey3: "+pKey3);
    byte[] pBytes3 = Encoding.ASCII.GetBytes(pKey3);
    MessageBox.Show("pBytes3: "+pBytes3);
    System.IO.MemoryStream mS1 = new System.IO.MemoryStream(pBytes3/*cBytes*/);
    CryptoStream cS1 = new CryptoStream(mS1, desObj.CreateDecryptor(), CryptoStreamMode.Read);
    cS1.Read(pBytes3/*cBytes*/, 0, pBytes3/*cBytes*/.Length);
    pBytes2 = mS1.ToArray();
    cS1.Close();
    mS1.Close();
    richTextBox1.Text = Encoding.ASCII.GetString(pBytes2);
}

现在我想做的是: 我的程序有 1 个richTextBox 和 2 个按钮,一个按钮用于加密文本框的文本,另一个用于解密。因此,如果您按下加密按钮,系统会要求您输入密钥(最大字符数:16),如果您输入的密钥的字符数少于 16,它会被填满,例如“测试”变成“test123456789123”。加密部分到目前为止工作,但我在解密它时遇到了麻烦。如果你按下解密按钮,你也会被要求输入一个密钥,它也会被填满,所以 test 变成了和上面一样的 16 个字符的密钥。但是在我输入“测试”之后,它给了我以下错误:

未处理的类型异常 'System.Security.Cryptography.CryptographicException' 发生在 mscorlib.dll

附加信息:字符间距无效,不能 删除。

希望有人知道该怎么做!在此先感谢:)

编辑: 所以这可以解密加密的文本:

private void button2_Click(object sender, EventArgs e)//DECRYPT
{
    //string pKey3 = InputBox("Decryption-Key", "Enter a Decryption-Key:");
    System.IO.MemoryStream mS1 = new System.IO.MemoryStream(cBytes);
    CryptoStream cS1 = new CryptoStream(mS1, desObj.CreateDecryptor(), CryptoStreamMode.Read);
    cS1.Read(cBytes, 0, cBytes.Length);
    pBytes2 = mS1.ToArray();
    cS1.Close();
    mS1.Close();
    string garbage = Encoding.ASCII.GetString(pBytes2);
    string decrypt = garbage.Substring(0, pBytes.Length);
    richTextBox1.Text = decrypt;
}

但这仅在格式化后直接起作用,而不是在我关闭程序并再次打开它时起作用,所以我想获取文本框中的文本并在作为解密密钥输入的字符串之后解密它pKey3

【问题讨论】:

  • 有谁能帮帮我吗!?
  • Encoding.ASCII.GetString(cBytes) 本质上是一种有损操作,因为密文可以包含每个可能的字节,而不必是有效的 ASCII 或 UTF-8 编码。使用 Base64 或类似的方法将二进制数据表示为字符串。

标签: c# encryption cryptography


【解决方案1】:

上面的代码不会存储然后恢复 IV 值。 IV 值将在首次使用desObj 时随机化。因此,如果密文直接用相同的对象实例解密,IV 仍然会被正确设置。如果您重新实例化该对象,则不会。通常IV与密文一起存储。

此外,上述代码似乎将密文存储为 ASCII。密文字节可以有任何值,包括底部的 32 个不可打印的字节和保留的值 127。相反,密文应该编码为base 64。当解码字节为ASCII时,信息可能会丢失。

注意事项:

  • 您应该使用 PBKDF(例如 PBKDF2)从密码中派生密钥。直接使用密码作为密钥是不安全的
  • 单 DES 或双密钥三重 DES 不再被认为是安全的,最好升级到 AES 并考虑在 IV 和密文上添加身份验证标签 (MAC)

【讨论】:

    【解决方案2】:

    我注意到您在解密期间获得了密码,但您将其用作 MemoryStream 中的内容。因为您已经在加密方法中设置了密码,所以看起来您尝试使用加密密码解密输入的密码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-22
      • 2015-11-02
      • 2011-06-17
      • 2015-07-31
      • 1970-01-01
      • 2021-11-01
      • 2012-12-21
      • 2019-12-15
      相关资源
      最近更新 更多