【问题标题】:Using SharpAESCrypt to encrypt strings使用 SharpAESCrypt 加密字符串
【发布时间】:2015-07-14 12:21:28
【问题描述】:

我决定在 C# 中使用 SharpAESCrypt 实现 AES 加密。根据他们的文档 (https://www.aescrypt.com/sharp_aes_crypt.html),您应该能够使用静态方法,提供密码字符串、纯文本输入流和输出流。我从输出流中得到的数据似乎全为零。

我怀疑我在将字符串转换为流并返回时做错了。任何人都可以看到下面的代码明显有什么问题吗? (它可以编译运行,但是newByteArray末尾是0)

    private void encryptMemStream()
    {
        byte[] byteArray = Encoding.UTF8.GetBytes(DecryptedTB.Text);
        using (MemoryStream plainText = new MemoryStream(byteArray))
        {
            using (MemoryStream encryptedData = new MemoryStream())
            {
                //plainText.Write(byteArray, 0, byteArray.Length);
                SharpAESCrypt.Encrypt(PasswordTB.Text, plainText, encryptedData);
                encryptedData.Position = 0;
                byte[] newByteArray = new byte[encryptedData.Length];
                newByteArray = encryptedData.ToArray();
                EncryptedTB.Text = Encoding.UTF8.GetString(newByteArray);
            }
        }
    }

编辑:此代码的本机实现使用 fileStreams,但它也应该与 MemoryStreams 一起使用。我将测试文件流并在此处添加我的结果。

更多编辑:

因此,当您使用文件流时,您会调用此代码

    //Code from the AES Crypt Library
    public static void Encrypt(string password, string inputfile, string outputfile)
    {
        using (FileStream infs = File.OpenRead(inputfile))
        using (FileStream outfs = File.Create(outputfile))
            Encrypt(password, infs, outfs);
    }

调用我一直直接调用的函数

    //Code from the AES Crypt Library
    public static void Encrypt(string password, Stream input, Stream output)
    {
        int a;
        byte[] buffer = new byte[1024 * 4];
        SharpAESCrypt c = new SharpAESCrypt(password, output, OperationMode.Encrypt);
        while ((a = input.Read(buffer, 0, buffer.Length)) != 0)
            c.Write(buffer, 0, a);
        c.FlushFinalBlock();
    }

使用 MemoryStream 和 FileStream 显然存在一些我不理解的细微差别。 FileStream 工作正常,其中 MemoryStream 返回一个空白数组...

【问题讨论】:

  • 使用流时应该使用using
  • 您能详细说明一下吗?
  • 我会避免使用 ascii。
  • 我会尝试其他编码类型。
  • 这并没有解决问题。

标签: c# aes


【解决方案1】:

快速的代码审查揭示了一些事情,包括从讨论中您面临的主要问题。有问题的行是

EncryptedTB.Text = Encoding.UTF8.GetString(newByteArray);

这一行获取 newByteArray 中的二进制数据并告诉您的代码它是一个有效的 UTF8 字节数组。几乎可以肯定它实际上不会是有效的 UTF8。它的一部分可能是(例如标头),但实际加密的数据不会是,因此您不应使用此方法获取字符串。

如果您需要将可打印的字符串放入某种文本框中,那么对二进制数据执行此操作的正确方法是通过 base64 编码。

EncryptedTB.Text = Convert.ToBase64String(newByteArray);

Base64 编码有效地采用三个字节(24 位)的组并将它们转换为四个字符的组。

我在这里的另一个注意事项是这两行:

byte[] newByteArray = new byte[encryptedData.Length];
newByteArray = encryptedData.ToArray();

您声明一个字节数组并为其分配一个新数组。然后您立即丢弃它,转而使用来自encryptedData.ToArray() 的数组。这不会将数据放入new byte[encryptedData.Length] 分配的数组中,而是创建一个新数组并将其放入newByteArray 变量中。最好是这样做:

byte[] newByteArray = encryptedData.ToArray();

完整的工作代码如下:

byte[] byteArray = Encoding.UTF8.GetBytes(sourceText);
Byte[] newByteArray;
using (MemoryStream plainText = new MemoryStream(byteArray))
{
    using (MemoryStream encryptedData = new MemoryStream())
    {
        SharpAESCrypt.Encrypt(password, plainText, encryptedData);
        newByteArray = encryptedData.ToArray();
    }
}
EncryptedTB.Text = Convert.ToBase64String(newByteArray);

【讨论】:

  • 谁能告诉我如何将字符串解密回普通文本?我收到Invalid header marker 之类的错误
  • 我使用了您建议的相同代码进行加密,并且工作正常。对于解密,我只将SharpAESCrypt.Encrypt 更改为SharpAESCrypt.Decrypt。在执行该行时,错误来了
  • @RealSteel:如果您的问题与此问题中的问题不同,那么您应该提出一个新问题。在其中尝试有足够的代码来重现问题 - 即显示您的加密方法和解密方法以及对它们中的每一个的示例调用(大概将加密的输出传递给解密方法)。该错误听起来像是您向解密方法传递了不正确的内容,并且需要完整的代码来诊断类似的内容...
猜你喜欢
  • 1970-01-01
  • 2012-12-21
  • 2010-11-22
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 2022-11-25
相关资源
最近更新 更多