【问题标题】:MemoryStream to String, and back to MemoryStream without adding any bytes (encodings, etc.)MemoryStream 到 String,然后返回到 MemoryStream 而不添加任何字节(编码等)
【发布时间】:2015-08-11 14:57:20
【问题描述】:

好的,我遇到了一些文章 herehere,但它们并没有完全满足我的需求,我遇到了一些麻烦。

我正在接收一段加密的数据作为内存流。我需要以某种方式将内存流写入文件(我编写模型的方式,作为字符串最好),然后从文件中检索字符串并将其作为内存流发送到要解密的服务。我只是使用流读取器将内存流存储为字符串,并使用编码将字符串读入内存。

问题是我收到一条错误消息,指出我的加密数据已损坏。我认为这意味着我以某种方式更改了字节。

以下是将内存流读入字符串的代码:

using (StreamReader reader = new StreamReader(dataKeyResponse.CiphertextBlob))
{
    encryptedDataKey = reader.ReadToEnd();
}

下面是读取从文件中检索到的字符串到内存流中的代码:

MemoryStream mStream = new MemoryStream(ASCIIEncoding.Default.GetBytes(encryptedKey));

我认为执行它的步骤是 ASCIIEncoding,但后来我实现了the workaround from above,将字节数组转换为内存流,并得到了同样的错误。

byte[] bytes = new byte[encryptedKey.Length*sizeof (char)];
System.Buffer.BlockCopy(encryptedKey.ToCharArray(), 0, bytes, 0, bytes.Length);

string decryptedKey;
using (MemoryStream mStream = new MemoryStream())
{
    mStream.Write(bytes, 0, bytes.Length);
    var decryptRequest = new DecryptRequest()
    {CiphertextBlob = mStream};
    var decryptResponse = client.Decrypt(decryptRequest);
    using (StreamReader reader = new StreamReader(decryptResponse.Plaintext))
    {
        decryptedKey = reader.ReadToEnd();
    }
}

我假设 (1) 某些东西以某种方式改变了数据,而不是其他错误; (2) 它在流->字符串或字符串->流转换中,而不是在字符串->文件或字符串post 判断它确实如此)。

确认输入和输出的字节应该是等效的,或者捕获文件中的内存流并将其发送回而不更改任何内容的方法都很棒。

【问题讨论】:

  • 不要将二进制(非文本)数据保存为字符串。毫无意义。就像一个字节流一样对待。
  • 以下是如何保存/加载内存流:stackoverflow.com/questions/8624071/…
  • 您不能将任意字节存储为字符串,因为strings have rules 和任意字节都不能。您必须以某种方式对字节进行编码(例如 Base64)或存储原始字节,而不是字符串。
  • 内存流是加密密钥,而使用密钥加密的数据是加密字符串。如果内存流保存为字符串,我可以将加密密钥和加密数据保存为同一个文件中的两个字符串。我不知道如何在内存流旁边保存一个字符串并将其读回......由于这只是一个概念证明,所以快速完成它是目前重要的......有没有办法在同一个文件中的内存流旁边保存一个字符串?
  • “如果内存流保存为字符串”;好吧,如果 32 大于 128,您可以将 decimal 保存在 int 中。但事实并非如此,你也不能。

标签: c# arrays string encryption


【解决方案1】:

假设您的 MemoryStream 包含以下输入数据:[0x01, 0x02, 0x03, 0x04] 当您使用流式阅读器读取它时,字符串的二进制表示将是:[0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04],因为字符串使用两个字节表示一个字符。之后您要做的是为“字节”变量分配 8 个字节而不是 4 个字节,并用第二个(修改后的)数据填充它。您可以使用 Convert.ToBase64String() 来获取字符串表示,也可以使用 FromBase64String() 将其解析回来。像这样的:

var testData = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
var inputStream = new MemoryStream(testData);

var inputAsString = Convert.ToBase64String(inputStream.ToArray());
Console.WriteLine(inputAsString);

var outputStream = new MemoryStream(Convert.FromBase64String(inputAsString));

var result = BitConverter.ToString(outputStream.ToArray());           
Console.WriteLine(result);

【讨论】:

  • 我可以使用任何编码来代替 Base64 吗?正在寻找任何 4 字节编码的好决定吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-20
  • 1970-01-01
相关资源
最近更新 更多