[英]Encrypting and decrypting File - Lead to “Bad Data”
I'm currently working a little object that will help me encrypt a file then decrypt it, and return it as a MemoryStream. 我当前正在工作的一个小对象将帮助我加密文件,然后解密它,并将其作为MemoryStream返回。 However, when I'm decrypting, I keep getting a "Bad data".
但是,当我解密时,我会不断收到“错误数据”。
"ExceptionMessage": "Bad Data.\ \ ",
"ExceptionType": "System.Security.Cryptography.CryptographicException",
The Class goes as follow 该课程如下
public class SignatureService {
private readonly DESCryptoServiceProvider _desCryptoServiceProvider;
private static byte[] _key = { 5, 6, 7, 2, 3, 4, 8, 1 };
private static byte[] _iv = { 5, 2, 3, 4, 1, 7, 4, 2 };
public SignatureService () {
_desCryptoServiceProvider = new DESCryptoServiceProvider();
}
public void SaveSignatureOnDisk ( Stream stream ) {
using ( var fs = new FileStream( "filepath", FileMode.Create, FileAccess.Write ) ) {
var cryptoStream = new CryptoStream( fs, _desCryptoServiceProvider.CreateEncryptor( _key, _iv ), CryptoStreamMode.Write );
var bytearrayinput = new byte[ stream.Length - 1 ];
stream.Read( bytearrayinput, 0, bytearrayinput.Length );
cryptoStream.Write( bytearrayinput, 0, bytearrayinput.Length );
}
}
public Stream ReadSignatureOnDisk () {
Stream returnedStream;
using ( var fs = new FileStream( "filepath", FileMode.Open, FileAccess.Read ) ) {
var cryptoStream = new CryptoStream( fs, _desCryptoServiceProvider.CreateDecryptor( _key, _iv ), CryptoStreamMode.Read );
string contents = new StreamReader( cryptoStream ).ReadToEnd();
byte[] unicodes = Encoding.Unicode.GetBytes( contents );
returnedStream = new MemoryStream( unicodes );
}
return returnedStream;
}
}
You made a few mistakes, the CryptoStream and the ICryptoTransform from CreateDecryptor
and CreateEncryptor
should be disposed. 您犯了一些错误,应该处理
CreateDecryptor
和CreateEncryptor
的CryptoStream和ICryptoTransform。 Also your stream.Read
is not reliable, Read is not guaranteed to actually read all of the bytes you asked it to. 另外,您的
stream.Read
不可靠,不能保证Read能够实际读取您要求的所有字节。 You must either loop till the Read returns 0 or use .CopyTo(
if you are on a version of .NET that has it. 您必须循环直到Read返回0为止,或者如果使用的是.NET版本,则必须使用
.CopyTo(
。
public void SaveSignatureOnDisk ( Stream stream )
{
using (var fs = new FileStream("filepath", FileMode.Create, FileAccess.Write))
using (var encryptor = _desCryptoServiceProvider.CreateEncryptor( _key, _iv))
using (var cryptoStream = new CryptoStream(fs, encryptor, CryptoStreamMode.Write))
{
stream.CopyTo(cryptoStream);
}
}
Your ReadSignatureOnDisk also has the same mistakes and needs to be fixed similarly. 您的ReadSignatureOnDisk也有相同的错误,需要类似地修复。
public Stream ReadSignatureOnDisk ()
{
Stream returnedStream = new MemoryStream();
using (var fs = new FileStream("filepath", FileMode.Open, FileAccess.Read))
using (var decryptor = _desCryptoServiceProvider.CreateDecryptor(_key, _iv))
using (var cryptoStream = new CryptoStream(fs, decryptor, CryptoStreamMode.Read);
{
cryptoStream.CopyTo(returnedStream);
}
returnedStream.Position = 0
return returnedStream;
}
If you want you could use my ReturnableCryptoStream class I wrote for another answer which allows you to return the original crypto stream and just let the caller dispose it. 如果愿意,可以使用我写的 ReturnableCryptoStream类, 我写了另一个答案 ,它允许您返回原始的加密流并只让调用者对其进行处理。
/// <summary>
/// Creates a class that creates a <see cref="CryptoStream"/> and wraps the disposing action of all the associated objects
/// </summary>
class ReturnableCryptoStream : CryptoStream
{
private readonly ICryptoTransform _transform;
private readonly IDisposable _algorithom;
public ReturnableCryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode, IDisposable algorithom)
: base(stream, transform, mode)
{
_transform = transform;
_algorithom = algorithom;
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
if (_transform != null)
_transform.Dispose();
if (_algorithom != null)
_algorithom.Dispose();
}
}
}
used like 使用像
public Stream ReadSignatureOnDisk ()
{
var fs = new FileStream("filepath", FileMode.Open, FileAccess.Read);
var serviceProvider = new DESCryptoServiceProvider()
var decryptor = serviceProvider.CreateDecryptor(_key, _iv);
var cryptoStream = new ReturnableCryptoStream(fs,
decryptor,
CryptoStreamMode.Read,
serviceProvider);
//note that I now make my own local copy of the service provider, you could use your
//existing one and pass in null to the ReturnableCryptoStream.
return cryptoStream ;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.