在 MySQL 中加密,在 C# 中解密

Posted

技术标签:

【中文标题】在 MySQL 中加密,在 C# 中解密【英文标题】:Encrypting in MySQL, Decrypting in C# 【发布时间】:2018-01-30 04:33:50 【问题描述】:

我在 mysql 中加密了我的数据,我将其存储为 BLOB,然后我需要在 C# 中对其进行解密,但我没有得到预期的结果。

MYSQL 中的 BLOB:

这是我的结果:

应该只是 PD001KY6900430

这是我的 C# 代码

string ConnectionString = "Data Source=win-3doecchgfbt;Initial Catalog=DWH;User id=sa;Password=Password123;";
        using (SqlConnection connection = new SqlConnection(ConnectionString))
        
            string query = "SELECT * FROM tb_investor";
            SqlDataAdapter adapter = new SqlDataAdapter();
            var command = new SqlCommand(query, connection);
            adapter.SelectCommand = command;

            DataTable dTable = new DataTable();

            adapter.Fill(dTable);
            for(var x =0; x < dTable.Rows.Count; x++)
            
                var dr = dTable.Rows;

                byte[] accNoByte = (byte[])dr[x].ItemArray[1];

                byte[] key = mkey("satu");

                var rkey = BitConverter.ToString(key).Replace("-", "");

                var decAccNo = decrypt_function(accNoByte, key);

            
        

这里是 mkey 方法:

Encoding winLatinCodePage = Encoding.GetEncoding(1252);
        byte[] key = Encoding.UTF8.GetBytes(skey);
        byte[] k = new byte[16]  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;
        for (int i = 0; i < key.Length; i++)
        
            k[i % 16] = (byte)(k[i % 16] ^ key[i]);
        

        return k;

这里是decrypt_function方法:

RijndaelManaged Crypto = null;
        MemoryStream MemStream = null;
        ICryptoTransform Decryptor = null;
        CryptoStream Crypto_Stream = null;
        StreamReader Stream_Read = null;
        string Plain_Text;

        try
        
            Crypto = new RijndaelManaged();
            Crypto.Key = Key;
            Crypto.Mode = CipherMode.ECB;
            Crypto.Padding = PaddingMode.None;

            MemStream = new MemoryStream(Cipher_Text);
            Crypto.GenerateIV();
            //Create Decryptor make sure if you are decrypting that this is here and you did not copy paste encryptor.
            Decryptor = Crypto.CreateDecryptor(Crypto.Key, Crypto.IV);

            //This is different from the encryption look at the mode make sure you are reading from the stream.
            Crypto_Stream = new CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read);

            //I used the stream reader here because the ReadToEnd method is easy and because it return a string, also easy.
            Stream_Read = new StreamReader(Crypto_Stream);
            Plain_Text = Stream_Read.ReadToEnd();
        
        finally
        
            if (Crypto != null)
                Crypto.Clear();

            MemStream.Flush();
            MemStream.Close();

        
        return Plain_Text;

请告诉我我犯的错误。

【问题讨论】:

【参考方案1】:

“PD001KY6900430”为14字节,AES(RijndaelManaged默认)块大小为16字节,因此输入数据需要填充为块大小的倍数,即PKCS#7 padding的最后两个0x02字节。因此,最后两个字节:“PD001KY6900430\u0002\u0002”(其中 \u0002 表示 UTF-16 中 0x02 的单个字节)是填充。

这通常通过为解密方法指定 PKCS#7 填充来处理(删除)。

修复:

更改Crypto.Padding = PaddingMode.None;Crypto.Padding = PaddingMode.PKCS7;

最好完全指定所有选项。

【讨论】:

我确实尝试删除填充,对于列 accNo,它可以工作,结果符合预期,但另一列出现错误,地址,错误:“填充无效 n 不能删除” 更正:如果我删除“Crypto.Mode = CipherMode.ECB; Crypto.Padding = PaddingMode.None;”,即使是 accNo 列,也会立即出现错误“填充无效,无法删除” 为什么要删除CipherMode.ECB?在accNo 上提供数据。 首先,我尝试删除paddingmode.None,accNo的结果符合预期,但是当这个明文“JL”的地址,BLOB的数据时出现错误“Padding is invalid....” . MESJID RAYA NO. 3 RT.004/002" 当我使用 ciphermode.ECB 和 paddingmode.none 时,问题是,我的结果中添加了一些字符,aaaand,长明文的结果被截断...... ..我对此一无所知...令人困惑

以上是关于在 MySQL 中加密,在 C# 中解密的主要内容,如果未能解决你的问题,请参考以下文章

使用 RijndaelManaged 在 C# 中加密/解密流

SQL Server FOR XML PATH('')) 加密数据需要在 C# 中解密

在 C# 中使用 Bouncy Castle 加密/解密

C#中RSA加密解密

解密 C# 中使用 RSA-OAEP 在 JavaScript 中加密的数据时出现 OAEP 填充错误

java c# 加密与解密对照