C# Rijndael 加密不接受除 "mykey123" 以外的任何密钥
C# Rijndael Encryption not accepting any Key except "mykey123"
我在 http://www.codeproject.com/Articles/26085/File-Encryption-and-Decryption-in-C 上找到了这个脚本。当我使用静态键 // string password = @"myKey1234"; // Your Key Here
时它工作正常。当我传入不同的密钥时,它不起作用 string password = @keyPwd;
。您可以在我的代码中看到我正在传递密钥以使其无法正常工作。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CSVEncrypts
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string inputFile = "";
string outputFilePath = "";
string oFilePathName = "";
// EncryptFile
private void EncryptFile(string inputFile, string outputFile,string keyPwd )
{
try
{
// string password = @"myKey123"; // Your Key Here
string password = @keyPwd;
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
string cryptFile = outputFile;
FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,RMCrypto.CreateEncryptor(key, key),CryptoStreamMode.Write);
FileStream fsIn = new FileStream(inputFile, FileMode.Open);
int data;
while ((data = fsIn.ReadByte()) != -1)
cs.WriteByte((byte)data);
fsIn.Close();
cs.Close();
fsCrypt.Close();
}
catch
{
MessageBox.Show("Encryption failed!", "Error");
}
}
// Decrypt
private void DecryptFile(string inputFile, string outputFile, string keyPwd)
{
{
//string password = @"myKey123"; // Your Key Here
string password = @keyPwd; // Your Key Here
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,
RMCrypto.CreateDecryptor(key, key),CryptoStreamMode.Read);
FileStream fsOut = new FileStream(outputFile, FileMode.Create);
int data;
while ((data = cs.ReadByte()) != -1)
fsOut.WriteByte((byte)data);
fsOut.Close();
cs.Close();
fsCrypt.Close();
}
}
private void button1_Click(object sender, EventArgs e)
{
if (inputFile != "")
{
oFilePathName = outputFilePath + "\" + textBox1.Text;
EncryptFile(inputFile, oFilePathName,keytextBox.Text);
}
}
private void button2_Click(object sender, EventArgs e)
{
if (inputFile != "") ;
{
oFilePathName = outputFilePath + "\" + textBox1.Text;
DecryptFile(inputFile, oFilePathName, keytextBox.Text);
}
}
private void button3_Click(object sender, EventArgs e)
{
OpenFileDialog InputOpenFileDialog1 = new OpenFileDialog();
if (InputOpenFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string strInfilename = InputOpenFileDialog1.FileName;
button3.Text = strInfilename;
inputFile = strInfilename;
outputFilePath = Path.GetDirectoryName(inputFile);
}
}
}
}
我假设 Rijndael 指的是 AES(高级加密标准),AES 是 Rijndael 的一个子集,块大小为 128 位,这就是您所需要的。
AES 密钥是128、192 或256 位,最好不要使用字符串,如果你先有一个字符串运行 通过PBKDF2 等密钥推导函数。键确实应该是字节数组,而不是字符串。使键的大小完全正确,这可能是你的问题。
CreateDecryptor
有两个参数,key 和 iv,不要把 key 也用在 iv 上,iv 被认为是 public.
从代码上看不清楚,需要查阅文档看是否默认模式是CBC,是否启用了PKCS#7(PKCS#5 padding互换使用)padding。
如果您想要开箱即用的安全加密:使用 RNCryptor, there is a C# version。您还将获得 multi-language/platform 互操作性。
获得正确的加密安全性并不容易,而且很容易犯下破坏安全性的错误。
密钥应该只包含与随机无法区分的位。编码为字节 的密码不是密钥 。特别是在使用 Unicode
编码(应该命名为 UTF16LE
)时,许多位都设置为零。这意味着“密钥”也不包含足够的熵。
要从密码创建密钥,您应该使用基于密码的密钥派生函数 (PBKDF) 派生它。在当前的 .NET Crypto API 中执行此操作的最佳方法可能是使用 class Rfc2898DeriveBytes which implements PBKDF2. PBKDF2 is defined in RFC 2898: PKCS #5: Password-Based Cryptography Specification V2.0。如果您想进行基于密码的加密,您可能需要阅读这篇文章。
我在 http://www.codeproject.com/Articles/26085/File-Encryption-and-Decryption-in-C 上找到了这个脚本。当我使用静态键 // string password = @"myKey1234"; // Your Key Here
时它工作正常。当我传入不同的密钥时,它不起作用 string password = @keyPwd;
。您可以在我的代码中看到我正在传递密钥以使其无法正常工作。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CSVEncrypts
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string inputFile = "";
string outputFilePath = "";
string oFilePathName = "";
// EncryptFile
private void EncryptFile(string inputFile, string outputFile,string keyPwd )
{
try
{
// string password = @"myKey123"; // Your Key Here
string password = @keyPwd;
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
string cryptFile = outputFile;
FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,RMCrypto.CreateEncryptor(key, key),CryptoStreamMode.Write);
FileStream fsIn = new FileStream(inputFile, FileMode.Open);
int data;
while ((data = fsIn.ReadByte()) != -1)
cs.WriteByte((byte)data);
fsIn.Close();
cs.Close();
fsCrypt.Close();
}
catch
{
MessageBox.Show("Encryption failed!", "Error");
}
}
// Decrypt
private void DecryptFile(string inputFile, string outputFile, string keyPwd)
{
{
//string password = @"myKey123"; // Your Key Here
string password = @keyPwd; // Your Key Here
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,
RMCrypto.CreateDecryptor(key, key),CryptoStreamMode.Read);
FileStream fsOut = new FileStream(outputFile, FileMode.Create);
int data;
while ((data = cs.ReadByte()) != -1)
fsOut.WriteByte((byte)data);
fsOut.Close();
cs.Close();
fsCrypt.Close();
}
}
private void button1_Click(object sender, EventArgs e)
{
if (inputFile != "")
{
oFilePathName = outputFilePath + "\" + textBox1.Text;
EncryptFile(inputFile, oFilePathName,keytextBox.Text);
}
}
private void button2_Click(object sender, EventArgs e)
{
if (inputFile != "") ;
{
oFilePathName = outputFilePath + "\" + textBox1.Text;
DecryptFile(inputFile, oFilePathName, keytextBox.Text);
}
}
private void button3_Click(object sender, EventArgs e)
{
OpenFileDialog InputOpenFileDialog1 = new OpenFileDialog();
if (InputOpenFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string strInfilename = InputOpenFileDialog1.FileName;
button3.Text = strInfilename;
inputFile = strInfilename;
outputFilePath = Path.GetDirectoryName(inputFile);
}
}
}
}
我假设 Rijndael 指的是 AES(高级加密标准),AES 是 Rijndael 的一个子集,块大小为 128 位,这就是您所需要的。
AES 密钥是128、192 或256 位,最好不要使用字符串,如果你先有一个字符串运行 通过PBKDF2 等密钥推导函数。键确实应该是字节数组,而不是字符串。使键的大小完全正确,这可能是你的问题。
CreateDecryptor
有两个参数,key 和 iv,不要把 key 也用在 iv 上,iv 被认为是 public.
从代码上看不清楚,需要查阅文档看是否默认模式是CBC,是否启用了PKCS#7(PKCS#5 padding互换使用)padding。
如果您想要开箱即用的安全加密:使用 RNCryptor, there is a C# version。您还将获得 multi-language/platform 互操作性。
获得正确的加密安全性并不容易,而且很容易犯下破坏安全性的错误。
密钥应该只包含与随机无法区分的位。编码为字节 的密码不是密钥 。特别是在使用 Unicode
编码(应该命名为 UTF16LE
)时,许多位都设置为零。这意味着“密钥”也不包含足够的熵。
要从密码创建密钥,您应该使用基于密码的密钥派生函数 (PBKDF) 派生它。在当前的 .NET Crypto API 中执行此操作的最佳方法可能是使用 class Rfc2898DeriveBytes which implements PBKDF2. PBKDF2 is defined in RFC 2898: PKCS #5: Password-Based Cryptography Specification V2.0。如果您想进行基于密码的加密,您可能需要阅读这篇文章。