我正在组织一些非常基本的对称加密/解密代码,以供将来使用。我能够成功地加密和解密。。。只有一个小问题。
下面是我的代码,它从一个流中读取,并对另一个流进行加密/解密:
public void Encrypt(Stream input, Stream output) {
byte[] key = Encoding.UTF8.GetBytes(_pw);
byte[] iv = Encoding.UTF8.GetBytes(GenerateInitVector());
RijndaelManaged rm = new RijndaelManaged();
CryptoStream cs = new CryptoStream(
output,
rm.CreateEncryptor(key, iv),
CryptoStreamMode.Write);
int data;
while ((data = input.ReadByte()) != -1)
cs.WriteByte((byte) data);
cs.Close();
}
public void Decrypt(Stream input, Stream output) {
byte[] key = Encoding.UTF8.GetBytes(_pw);
byte[] iv = Encoding.UTF8.GetBytes(GenerateInitVector());
RijndaelManaged rm = new RijndaelManaged();
CryptoStream cs = new CryptoStream(
input,
rm.CreateDecryptor(key, iv),
CryptoStreamMode.Read);
int data;
while ((data = cs.ReadByte()) != -1)
output.WriteByte((byte) data);
cs.Close();
}
仅供参考,方法GenerateInitVector()始终返回相同的值。
这是我的测试文件。
hello
world
this
is
a
word
list
当我尝试从FileStream打开/解密到FileStream时,使用以下方法,一切都很正常:
public void Encrypt(string inputPath, string outputPath) {
FileStream input = new FileStream(inputPath, FileMode.Open);
FileStream output = new FileStream(outputPath, FileMode.Create);
Encrypt(input, output);
output.Close();
input.Close();
}
public void Decrypt(string inputPath, string outputPath) {
FileStream input = new FileStream(inputPath, FileMode.Open);
FileStream output = new FileStream(outputPath, FileMode.Create);
Decrypt(input, output);
output.Close();
input.Close();
}
当我尝试将文件解密到MemoryStream中,然后将转换为字符数组的字节加载到StringBuilder中,最后将其作为字符串输出到控制台时,我会进入控制台:
?hello
world
this
is
a
word
list
我所有的文本前面都有一个额外的问号。下面是我的解密方法:
public StringBuilder Decrypt(string inputPath) {
FileStream input = new FileStream(inputPath, FileMode.Open);
byte[] buffer = new byte[4096];
MemoryStream output = new MemoryStream(buffer);
Decrypt(input, output);
StringBuilder sb = new StringBuilder(4096);
sb.Append(Encoding.UTF8.GetChars(buffer, 0, (int) output.Position));
input.Close();
output.Close();
return sb;
}
我在这里读过一些类似的关于BOM和C#的东西,它们悄悄地把未知的东西写成“?”字符:
Result of RSA encryption/decryption has 3 question marks
因此,我已经加倍确保我使用的是UTF-8编码。尽管如此,我还是看到了这个额外的问号。为了完整起见,我还编写了以下方法来将StringBuilder中的内容加密到文件中:
public void Encrypt(string outputPath, StringBuilder builder) {
char[] buffer = new char[builder.Length];
builder.CopyTo(0, buffer, 0, builder.Length);
byte[] buf = Encoding.UTF8.GetBytes(buffer);
MemoryStream input = new MemoryStream(buf);
FileStream output = new FileStream(outputPath, FileMode.Create);
Encrypt(input, output);
output.Close();
input.Close();
}
然后我进行交叉检查:
var builder = new StringBuilder();
builder.Append("Hello world.");
Encrypt("test.txt.enc", builder);
Decrypt("test.txt.enc", "test.txt");
builder = Decrypt("test.txt.enc");
Console.WriteLine(builder.ToString());
对于文件test.txt,一切正常。奇怪的是,对于控制台上打印的文本
不
前面的额外问号:
Hello world.
整个过程有什么问题?