简体   繁体   English

加密和解密文件-导致“错误数据”

[英]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. 您犯了一些错误,应该处理CreateDecryptorCreateEncryptor的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM