简体   繁体   English

C#cryptoStream.Read错误

[英]C# cryptoStream.Read error

Greeting C# programmer! 问候C#程序员! I try to build a DLL using C# to crypt and decrypt by VBS script a VBS file. 我尝试使用C#构建DLL,以通过VBS脚本对VBS文件进行加密和解密。

My code is this: 我的代码是这样的:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.IO;

namespace DELTAGE
{
    [System.Runtime.InteropServices.ComVisible(true)]
    [System.Runtime.InteropServices.ProgId("DELTAGE.DLL")]
    [System.Runtime.InteropServices.Guid("aaaaaaaa-0000-bbbb-1111-cccccccccccccc")]
    public class DeltaGeIO
    {
        // This constant string is used as a "salt" value for the PasswordDeriveBytes function calls.
        // This size of the IV (in bytes) must = (keysize / 8).  Default keysize is 256, so the IV must be
        // 32 bytes long.  Using a 16 character string here gives us 32 bytes when converted to a byte array.
        private const string initVector = "aa00bb11cc22dd33";

        // This constant is used to determine the keysize of the encryption algorithm.
        private const int keysize = 256;

        private string debug;

        public string cryptDecryptScript(string nameFileToCrypt)
        {
            try
            {
                string prova = writeVBScriptEncrypt(nameFileToCrypt, "");
                prova = writeVBScriptDecrypt("testCrypt.txt");
                return prova;
            }
            catch
            {
                return debug;
            }
        }

        public string writeVBScriptEncrypt(string nameFile, string nameScript)
        {
            byte[] bytes = System.IO.File.ReadAllBytes(nameFile);
            string[] lines = new string[1];
            lines[0] = this.EncryptBytes(bytes, "test");
            try
            {
                System.IO.File.Delete("testCrypt.txt");
            }
            catch
            {
                debug = "WVBSSE - i cannot delete testCrypt.txt file";
            }
            System.IO.File.WriteAllLines("testCrypt.txt", lines);
            return "OK file Encrypted";
        }

        public string writeVBScriptDecrypt(string nameFile)
        {
            byte[] bytes = System.IO.File.ReadAllBytes(nameFile);
            string[] lines = new string[1];
            lines[0] = this.DecryptBytes(bytes, "test");
            System.IO.File.WriteAllLines("testDecrypt.vbs", lines);
            try
            {
                System.IO.File.Delete("testCrypt.txt");
            }
            catch
            {
                debug = "WVBSSD - i cannot delete testCrypt.txt file";
            }
            return "OK file Decrypted";
        }

        private string Encrypt(string plainText, string passPhrase)
        {
            byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector);
            byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
            PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
            byte[] keyBytes = password.GetBytes(keysize / 8);
            RijndaelManaged symmetricKey = new RijndaelManaged();
            symmetricKey.Mode = CipherMode.CBC;
            ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
            cryptoStream.FlushFinalBlock();
            byte[] cipherTextBytes = memoryStream.ToArray();
            memoryStream.Close();
            cryptoStream.Close();
            return Convert.ToBase64String(cipherTextBytes);
        }

        private string Decrypt(string cipherText, string passPhrase)
        {
            byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
            byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
            PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
            byte[] keyBytes = password.GetBytes(keysize / 8);
            RijndaelManaged symmetricKey = new RijndaelManaged();
            symmetricKey.Mode = CipherMode.CBC;
            ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
            MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
            CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
            byte[] plainTextBytes = new byte[cipherTextBytes.Length];
            int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
            memoryStream.Close();
            cryptoStream.Close();
            return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
        }

        private string EncryptBytes(byte[] plainText, string passPhrase)
        {
            byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector);
            byte[] plainTextBytes = plainText;
            PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
            byte[] keyBytes = password.GetBytes(keysize / 8);
            RijndaelManaged symmetricKey = new RijndaelManaged();
            symmetricKey.Mode = CipherMode.CBC;
            ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
            cryptoStream.FlushFinalBlock();
            byte[] cipherTextBytes = memoryStream.ToArray();
            memoryStream.Close();
            cryptoStream.Close();
            return Convert.ToBase64String(cipherTextBytes);
        }

        private string DecryptBytes(byte[] cipherText, string passPhrase)
        {
            byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
            byte[] cipherTextBytes = cipherText;
            PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
            byte[] keyBytes = password.GetBytes(keysize / 8);
            RijndaelManaged symmetricKey = new RijndaelManaged();
            symmetricKey.Mode = CipherMode.CBC;
            ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes);
            MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
            CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
            byte[] plainTextBytes = new byte[cipherTextBytes.Length];
            debug = "here 1"; 
            int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
            debug = "here 1";
            memoryStream.Close();
            debug = "here 3" + decryptedByteCount.ToString();
            cryptoStream.Close();
            debug = "here 4";
            return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
        }
    }
}

So, if i try to econde and decode a string using Encrypt and Decrypt it work fine. 因此,如果我尝试使用加密和解密对字符串进行编码和解码,则可以正常工作。

But if i try to encrypt a file and decrypt crypted file using EncryptBytes and DecryptBytes i have an error to this code line: 但是,如果我尝试使用EncryptBytes和DecryptBytes加密文件并解密加密的文件,则此代码行将出现错误:

int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);

Any Ideas? 有任何想法吗? Thanks 谢谢

Ps VBS code to call dll is this: PS VBS调用dll的代码是这样的:

Dim mObj, strResult
set mObj = CreateObject("DELTAGE.DLL")
strResult = mObj.cryptDecryptScript("file.vbs")
MsgBox "Result: " + strResult

Before you create your file, you convert the "encrypted" bytes to a base64 string. 在创建文件之前,请将“加密的”字节转换为base64字符串。 When you read this file, you don't convert back the base64 string to the "encrypted" bytes. 读取此文件时,不会将base64字符串转换回“已加密”字节。

To solve your problem you could update your WriteVBScriptDecrypt method like this: 为了解决您的问题,您可以像这样更新WriteVBScriptDecrypt方法:

public string writeVBScriptDecrypt(string nameFile)
{
  var base64EncryptedBytes = File.ReadAllText(nameFile);
  byte[] bytes = Convert.FromBase64String(base64EncryptedBytes);

  ...
}

A better way is to get rid of the Base64 conversion, you can write the bytes directly to a file instead of converting it to a base64 string first. 更好的方法是摆脱Base64转换,您可以将字节直接写入文件中,而不必先将其转换为base64字符串。

You should also consider the using {} statement to make sure that everything is disposed nicely. 您还应该考虑使用using {}语句,以确保一切都妥善处理。

 public class DeltaGeIO
{
    // This constant string is used as a "salt" value for the PasswordDeriveBytes function calls.
    // This size of the IV (in bytes) must = (keysize / 8).  Default keysize is 256, so the IV must be
    // 32 bytes long.  Using a 16 character string here gives us 32 bytes when converted to a byte array.
    private const string initVector = "aa00bb11cc22dd33";

    // This constant is used to determine the keysize of the encryption algorithm.
    private const int keysize = 256;

    private string debug;

    public string cryptDecryptScript(string nameFileToCrypt)
    {
        try
        {
            string prova = writeVBScriptEncrypt(nameFileToCrypt, "");
            prova = writeVBScriptDecrypt("testCrypt.txt");
            return prova;
        }
        catch
        {
            return debug;
        }
    }

    public string writeVBScriptEncrypt(string nameFile, string nameScript)
    {
        byte[] bytes = System.IO.File.ReadAllBytes(nameFile);
        byte[] encryptedBytes = this.EncryptBytes(bytes, "test");
        try
        {
            File.Delete("testCrypt.txt");
        }
        catch
        {
            debug = "WVBSSE - i cannot delete testCrypt.txt file";
        }

        File.WriteAllBytes("testCrypt.txt", encryptedBytes);
        return "OK file Encrypted";
    }

    public string writeVBScriptDecrypt(string nameFile)
    {
       var encryptedBytes = File.ReadAllBytes(nameFile);
       byte[] decryptedBytes = this.DecryptBytes(encryptedBytes, "test");
       System.IO.File.WriteAllBytes("testDecrypt.vbs", decryptedBytes);
        try
        {
            System.IO.File.Delete("testCrypt.txt");
        }
        catch
        {
            debug = "WVBSSD - i cannot delete testCrypt.txt file";
        }
        return "OK file Decrypted";
    }

    private byte[] EncryptBytes(byte[] plainText, string passPhrase)
    {
       byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector);
       byte[] plainTextBytes = plainText;
       PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
       byte[] keyBytes = password.GetBytes(keysize / 8);
       using (RijndaelManaged symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC})
       {
          using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes))
          using (MemoryStream memoryStream = new MemoryStream())
          using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
          {
             cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
             cryptoStream.FlushFinalBlock();
             byte[] cipherTextBytes = memoryStream.ToArray();
             return cipherTextBytes;
          }
       }
    }

    private byte[] DecryptBytes(byte[] cipherText, string passPhrase)
    {
        byte[] initVectorBytes = Encoding.UTF8.GetBytes(initVector);
        byte[] cipherTextBytes = cipherText;
        PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null);
        byte[] keyBytes = password.GetBytes(keysize / 8);
        using (RijndaelManaged symmetricKey = new RijndaelManaged(){Mode = CipherMode.CBC})
        using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes))
        using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
        {
           byte[] buffer = new byte[cipherTextBytes.Length];
           int decryptedByteCount = cryptoStream.Read(buffer, 0, buffer.Length);
           byte[] copy = new byte[decryptedByteCount];
           Array.Copy(buffer, copy, decryptedByteCount);

           return copy;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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