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

时间:2016-02-10 12:46:25

标签: c# encryption cryptography

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

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,则填写起来,即f.e。 “test”变为“test123456789123”。加密部分到目前为止工作,但我解密它有麻烦。如果你按下解密按钮,你也会被要求输入一个键,并且它也被填满,所以测试变成了与上面相同的16字符键。但在我输入“test”后,它给了我以下错误:

  

未处理的类型异常   发生'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;
}

但这只能在格式化之后直接工作,而不是在我关闭程序并再次打开它时,所以我想在文本框中获取文本并在此情况下作为解密密钥输入的字符串后解密{{1 }}!

2 个答案:

答案 0 :(得分:1)

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

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

注意:

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

答案 1 :(得分:0)

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