如何使用特定密钥解密加密字符串

本文关键字:解密 加密 字符串 密钥 何使用 | 更新日期: 2023-09-27 18:34:05

首先,这是我到目前为止的代码。

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,它就会被填满,例如"test"变为"test123456789123"。到目前为止,加密部分可以正常工作,但是我在解密时遇到了麻烦。如果您按下解密按钮,您也会被要求输入一个密钥,并且它也会被填满,因此 test 将变为与上面相同的 16 个字符的密钥。但是在我输入"测试"后,它给了我以下错误:

类型的未处理异常 "System.Security.Cryptography.CryptographicException"发生在 姆科利布.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

如何使用特定密钥解密加密字符串

上面的

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

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

笔记:

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

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