首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C# cryptoStream.Read错误

C# cryptoStream.Read错误
EN

Stack Overflow用户
提问于 2013-06-25 18:46:50
回答 1查看 1.7K关注 0票数 0

问候C#程序员!我尝试用C#建立一个动态链接库,用VBS脚本对VBS文件进行加密和解密。

我的代码是:

代码语言:javascript
复制
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);
        }
    }
}

因此,如果我尝试使用Encrypt和Decrypt对字符串进行编码和解码,则可以很好地工作。

但是,如果我尝试使用EncryptBytes和DecryptBytes来加密文件和解密加密文件,我会得到以下代码行的错误:

代码语言:javascript
复制
int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);

有什么想法吗?谢谢

附注:调用dll的VBS代码如下:

代码语言:javascript
复制
Dim mObj, strResult
set mObj = CreateObject("DELTAGE.DLL")
strResult = mObj.cryptDecryptScript("file.vbs")
MsgBox "Result: " + strResult
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-25 19:35:46

在创建文件之前,您需要将“加密”字节转换为base64字符串。当您读取此文件时,您不会将base64字符串转换回“加密”字节。

要解决您的问题,您可以像这样更新您的WriteVBScriptDecrypt方法:

代码语言:javascript
复制
public string writeVBScriptDecrypt(string nameFile)
{
  var base64EncryptedBytes = File.ReadAllText(nameFile);
  byte[] bytes = Convert.FromBase64String(base64EncryptedBytes);

  ...
}

一种更好的方法是摆脱Base64转换,您可以直接将字节写入文件,而不是先将其转换为base64字符串。

您还应该考虑使用{}语句,以确保所有内容都被很好地处理。

代码语言:javascript
复制
 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;
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17295292

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档