c# - 前 16 个字节的 IV 从解密的字符串中删除?C#/Python3
问题描述
我想知道为什么我的所有字符串的前 16 个字节都被加密,然后在被解密时丢失了,如果可能的话如何解决这个问题。我在 c# 中像这样加密
public static string EncryptString(string b_key, string plainText)
{
byte[] iv = new byte[16];
byte[] array;
using (Aes aes = Aes.Create())
{
aes.Key = Convert.FromBase64String(b_key);
aes.IV = iv;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
{
streamWriter.Write(plainText);
}
array = memoryStream.ToArray();
}
}
}
return Convert.ToBase64String(array);
}
并像这样在python3中解密
enc = base64.b64decode(self.text)
iv = enc[:16]
cipher = AES.new(self.key, AES.MODE_CBC, iv)
plain_text = cipher.decrypt(enc[16:])
plain_text = self.dePKCS7_padding(plain_text)
return plain_text
可以读取前 16 个字节吗?或必须用于加密。我也希望它加密安全,但前 16 个字节很重要,这可能吗?无论如何要在 c# 或 python3 中解决这个问题?
解决方案
根据@MichaelFehr 和@user9014097 的评论和输入中的讨论,我想出了以下代码。
在此代码中IV
,AES 将在AES.Create()
调用时创建随机值。同样将用于加密值的结果。
decryptString 方法将从iv
传入的加密字符串中捕获值,并在解密字符串时将其分配给 AES。
public static string EncryptString(string b_key, string plainText)
{
byte[] array;
using (Aes aes = Aes.Create())
{
aes.Key = Convert.FromBase64String(b_key);
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using (MemoryStream memoryStream = new MemoryStream())
{
// Adding aes.IV to the stream's start.
memoryStream.Write(aes.IV);
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter streamWriter = new StreamWriter(cryptoStream))
{
streamWriter.Write(plainText);
}
}
array = memoryStream.ToArray();
}
}
// The final encrypted outcome will be aes.IV+encryptedtext.
return Convert.ToBase64String(array);
}
public static string DecryptString(string key, string cipherText)
{
//input is iv+encrypted text, convert them to byte array.
byte[] buffer = Convert.FromBase64String(cipherText);
// byte array for iv
byte[] iv = new byte[16];
// byte array for rest of the cipher text.
byte[] cipherBuffer = new byte[buffer.Length - 16];
// copy first 16 bytes from the cipher text to iv.
Buffer.BlockCopy(buffer, 0, iv, 0, 16);
// copy rest of the cipher text to the cipher buffer to be decrypted.
Buffer.BlockCopy(buffer, 16, cipherBuffer, 0, buffer.Length - 16);
using (Aes aes = Aes.Create())
{
aes.Key = Convert.FromBase64String(key);
aes.IV = iv;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using (MemoryStream memoryStream = new MemoryStream(cipherBuffer))
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
using (StreamReader streamReader = new StreamReader(cryptoStream))
{
return streamReader.ReadToEnd();
}
}
}
}
}
在编写上面的代码时,我有以下假设。
- 长度
IV
为 16。 - Python 代码(上面共享)不需要根据某些特定字符拆分输入文本。它将前 16 个字节作为
IV
值,其余字节作为密文。
我能够使用上述方法在 C# 中成功加密和解密值。
我无法解密 python 代码中的值,因为我几乎不知道如何使用 python。
您可以在 python 中测试上述加密的结果来解密它。让我知道它是否按预期工作。
我希望这能帮助你解决你的问题。
推荐阅读
- javascript - 如何使用固定标题导出 .PDF 版本的“ag-grid”?
- android - 我想使用 kotlin 多平台为 android 和 ios 发出网络获取请求,如何?
- c# - 无法启动 dotnet 核心进程。添加工具失败
- msix - 为什么VS 2019在我创建.msix包时将“_Test”附加到文件夹名称
- ruby - 使用数组中的值扩展散列数组
- python - tkinter - 如果错误未修复,如何不处理进一步的代码 - messagebox.showerror()
- load-balancing - abp后台jobmanager和负载均衡
- vue.js - 错误 vue.js 中“todo”道具的意外突变(我正在使用 vue3)
- reactjs - 使用 npx create-react-app 创建应用程序时显示消息“Model Parameter is Mandatory”的 React JS
- vue.js - 此 set-cookie 已被阻止,因为它具有 samesite=lax