簡體   English   中英

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

[英]How to Decrypt an Encrypted String using a specific Key

首先,這是到目前為止的代碼。

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,則該字符將被填滿,fe“ test”將變為“ test123456789123”。 到目前為止,加密部分已經可以使用,但是我在解密時遇到了麻煩。 如果您按下解密按鈕,也會要求您輸入密鑰,並且密鑰也被填滿,因此測試將變成與上述相同的16個字符的密鑰。 但是在我輸入“測試”之后,它給了我以下錯誤:

mscorlib.dll中發生了類型為'System.Security.Cryptography.CryptographicException'的未處理異常

附加信息:字符間距無效,不能刪除。

希望有人知道該怎么做! 提前致謝 :)

編輯:所以這可以解密加密的文本:

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。 而是應將密文編碼base64 。將字節解碼為ASCII時,信息可能會丟失。

筆記:

  • 您應該使用PBKDF(例如PBKDF2)從密碼派生密鑰。 直接使用密碼作為密鑰是不安全的
  • 單DES或雙密鑰三DES不再被認為是安全的,可以更好地升級到AES,並考慮在IV和密文上添加身份驗證標簽(MAC)

乍一看,我注意到您在解密過程中獲得了密碼,但是您將其用作MemoryStream中的內容。 由於您已經在加密方法中設置了密碼,因此您似乎嘗試使用加密密碼解密輸入的密碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM