在 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# 中解密