我目前正在处理一个小对象,它将帮助我加密文件然后对其进行解密,并将其作为MemoryStream返回。但是,当我正在解密时,我不断收到“错误数据”。
"ExceptionMessage": "Bad Data.\ \ ",
"ExceptionType": "System.Security.Cryptography.CryptographicException",
课程如下
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;
}
}
答案 0 :(得分:1)
你犯了一些错误,应该处理来自CreateDecryptor
和CreateEncryptor
的CryptoStream和ICryptoTransform。此外,stream.Read
不可靠,不保证读取实际读取您要求的所有字节。您必须循环直到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);
}
}
您的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;
}
如果你想要,你可以使用我的ReturnableCryptoStream类I wrote for another answer,它允许你返回原始的加密流,并让调用者处理它。
/// <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();
}
}
}
像
一样使用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 ;
}