【问题标题】:Encoding to use to convert Bytes array to String and vice-versa用于将字节数组转换为字符串的编码,反之亦然
【发布时间】:2011-11-03 14:51:58
【问题描述】:

我使用这段代码来加密一个字符串(基本上这是Rijndael class on MSDN上给出的例子):

public static String AESEncrypt(String str2Encrypt, Byte[] encryptionKey, Byte[] IV)
{
    Byte[] encryptedText;

    using (RijndaelManaged rijAlg = new RijndaelManaged())
    {
        // Use the provided key and IV
        rijAlg.Key = encryptionKey;
        rijAlg.IV = IV;

        // Create a decrytor to perform the stream transform
        ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

        // Create the streams used for encryption
        using (MemoryStream msEncrypt = new MemoryStream())
        using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
        {
            using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
            {
                // Write all data to the stream
                swEncrypt.Write(str2Encrypt);
            }

            encryptedText = msEncrypt.ToArray();
        }
    }

    return Encoding.Default.GetString(encryptedText);
}

我使用Encoding.Default 将字节数组转换为字符串,但我不确定这是一个好的解决方案。我的目标是将加密文本(例如密码...)存储在文件中。我应该继续使用Encoding.Default 还是使用Encoding.UTF8Encoding 或其他方式?

如果将文件移动到不同的操作系统上,当我尝试加密和解密它们时,这会对存储的值产生负面影响吗?

【问题讨论】:

    标签: c# string encoding bytearray


    【解决方案1】:

    您应该绝对不使用Encoding 将任意二进制数据转换为文本。 Encoding 用于当您获得真正是编码文本的二进制数据时 - 这不是。

    改为使用Convert.ToBase64String 将二进制数据编码为文本,然后使用Convert.FromBase64String 解码。

    【讨论】:

    • 谢谢乔恩。让我远离严重的错误。
    • @Jon Skeet,请帮助我理解您的评论“编码适用于当您获得真正是编码文本的二进制数据时”。如果我有一个 xml 数据并且我将其加密为一个字节数组,那个xml被认为是编码文本吗?
    • @RennishJoseph:加密后,它不是编码文本,不——不是Encoding 处理的方式。您将使用Encoding 将XML 文本转换为二进制数据,然后对其进行加密以获得更多二进制数据。稍后,您将解密二进制数据(结果仍然是二进制数据),并使用Encoding 将结果转换回文本。
    【解决方案2】:

    是的,Encoding.Default 是您机器的当前 ANSI 代码页,并且在多台机器/语言环境之间可能会有所不同。如果数据是文本数据并使其可移植,则需要使用固定的编码格式,例如 UTF8。

    但是,由于您的数据不是文本数据,因此您不能尝试使用任何文本编码来转换为字符串。最好的选择是使用十六进制或 Base64 编码或将其保存为 blob/byte 数组。

    【讨论】:

    • 这显然是不是文本数据——它是执行加密的结果,所以它是任意二进制数据。任何Encoding 在这里都不合适。
    • 是的,一旦我知道数据根本不是文本,就澄清了一点。
    【解决方案3】:

    如果您的目标是将加密信息存储在文件中,并且您有一个字节数组,则应该直接存储它 - 根本不要将其转换为字符串。 例如,在 C# 中您可以使用File.WriteAllBytes 将字节数组直接写入文件。请记住,文件保存的是字节,而不是字符串(如果您将字符串写入文件,则将使用某种 Encoding 将其转换为字节,即使您使用的技术并未明确引用 Encoding )。

    如果您确实需要将字节数组存储为字符串(例如,因为它将存储在 JSON 中),那么最常见的技术是使用 base64 和 Convert.ToBase64String,正如 Jon 提到的那样。

    (在非加密应用程序中,您可能有一个 byte[],其中包含 ASCII 和二进制数据的混合,并且您希望将其转换为字符串。在这种情况下,base64 工作正常,但它隐藏了文本 - 字节数组输入字符串格式类似于 base64,除了保留 ASCII 的运行 - Loyc.Essentials NuGet 包中的 C# version,Java 版本 here)

    【讨论】:

      【解决方案4】:

      我在这里不是 100% 确定,但我认为 Encoding.Default 指的是系统默认编码,是的,它可以从系统更改为系统..

      如果我在哪里,我会使用 UTF8 或其他不会因系统而异的编码..

      更多关于扩展 ascii 的信息请看这里

      http://en.wikipedia.org/wiki/Extended_ASCII

      【讨论】:

      • 不,使用 UTF-8 不是 一个好的解决方案 - 这个二进制数据是 not UTF-8 编码的文本;它是任意二进制数据。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多