MemoryStream 到 String,然后返回到 MemoryStream,而不添加任何字节(编码等)
MemoryStream to String, and back to MemoryStream without adding any bytes (encodings, etc.)
好的,我看过一些文章 here and here,但它们并没有完全满足我的需要,我 运行 遇到了一些麻烦。
我正在接收一段作为内存流的加密数据。我需要以某种方式将内存流写入文件(我编写模型的方式,最好是字符串),然后从文件中检索字符串并将其作为内存流发送到要解密的服务。我只是使用流读取器将内存流存储为字符串,并使用编码将字符串读入内存。
问题是我收到一条错误消息,提示我的加密数据已损坏。我认为这意味着我以某种方式更改了字节。
这是将内存流读入字符串的代码:
using (StreamReader reader = new StreamReader(dataKeyResponse.CiphertextBlob))
{
encryptedDataKey = reader.ReadToEnd();
}
下面是将从文件中检索到的字符串读取到内存流中的代码:
MemoryStream mStream = new MemoryStream(ASCIIEncoding.Default.GetBytes(encryptedKey));
我以为是ASCIIEncoding这一步,后来我实现了the workaround from above,把byte数组转成memorystream,结果还是一样的错误。
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) 是在stream -> string or string -> stream transition,而不是string -> file or string <- file transition; (3) 传入和传出数据的完美副本将解决问题——传入的数据应该是 "plaintext" 加密版本;也许有人期望我对传入和传出的流进行编码(编码甚至会更改数据吗?我是从它所做的 post 判断的)。
要么确认字节应该等效于进出,要么在文件中捕获内存流,然后在不更改任何内容的情况下将其发回,这将是很棒的。
假设您的 MemoryStream 包含以下输入数据:[0x01, 0x02, 0x03, 0x04]
当您使用 streamreader 读取它时,您的字符串的二进制表示将是:[0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04],因为字符串使用两个字节表示一个字符。之后您要做的是为 "bytes" 变量分配 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);
好的,我看过一些文章 here and here,但它们并没有完全满足我的需要,我 运行 遇到了一些麻烦。
我正在接收一段作为内存流的加密数据。我需要以某种方式将内存流写入文件(我编写模型的方式,最好是字符串),然后从文件中检索字符串并将其作为内存流发送到要解密的服务。我只是使用流读取器将内存流存储为字符串,并使用编码将字符串读入内存。
问题是我收到一条错误消息,提示我的加密数据已损坏。我认为这意味着我以某种方式更改了字节。
这是将内存流读入字符串的代码:
using (StreamReader reader = new StreamReader(dataKeyResponse.CiphertextBlob))
{
encryptedDataKey = reader.ReadToEnd();
}
下面是将从文件中检索到的字符串读取到内存流中的代码:
MemoryStream mStream = new MemoryStream(ASCIIEncoding.Default.GetBytes(encryptedKey));
我以为是ASCIIEncoding这一步,后来我实现了the workaround from above,把byte数组转成memorystream,结果还是一样的错误。
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) 是在stream -> string or string -> stream transition,而不是string -> file or string <- file transition; (3) 传入和传出数据的完美副本将解决问题——传入的数据应该是 "plaintext" 加密版本;也许有人期望我对传入和传出的流进行编码(编码甚至会更改数据吗?我是从它所做的 post 判断的)。
要么确认字节应该等效于进出,要么在文件中捕获内存流,然后在不更改任何内容的情况下将其发回,这将是很棒的。
假设您的 MemoryStream 包含以下输入数据:[0x01, 0x02, 0x03, 0x04] 当您使用 streamreader 读取它时,您的字符串的二进制表示将是:[0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04],因为字符串使用两个字节表示一个字符。之后您要做的是为 "bytes" 变量分配 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);