C# 往返Unicode转换返回不同的字节[]数组
我正在修补RSA数据签名 我使用的是纯文本字符串,我将其转换为字节数组。然后生成私有证书,对字节数组进行签名,然后生成公钥 接下来,我将使用相同的字节数组来验证签名 但我想在两个步骤之间将签名转换为字符串-想法是稍后将其附加到正在签名的文件中C# 往返Unicode转换返回不同的字节[]数组,c#,arrays,string,rsa,type-conversion,C#,Arrays,String,Rsa,Type Conversion,我正在修补RSA数据签名 我使用的是纯文本字符串,我将其转换为字节数组。然后生成私有证书,对字节数组进行签名,然后生成公钥 接下来,我将使用相同的字节数组来验证签名 但我想在两个步骤之间将签名转换为字符串-想法是稍后将其附加到正在签名的文件中 static void TestSigning(string privateKey) { string data = "TEST_TEST-TEST+test+TEst"; Console.WriteLine("==
static void TestSigning(string privateKey)
{
string data = "TEST_TEST-TEST+test+TEst";
Console.WriteLine("==MESSAGE==");
Console.WriteLine(data);
byte[] dataByte = Encoding.Unicode.GetBytes(data);
using (var rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString(privateKey);
var publicKey = rsa.ToXmlString(false);
byte[] signature = rsa.SignData(dataByte, CryptoConfig.MapNameToOID("SHA512"));
string signatureString = Encoding.Unicode.GetString(signature);
byte[] roundtripSignature = Encoding.Unicode.GetBytes(signatureString);
Console.WriteLine("==TEST==");
Console.WriteLine(signature.Length.ToString());
Console.WriteLine(roundtripSignature.Length.ToString());
using (var checkRSA = new RSACryptoServiceProvider())
{
checkRSA.FromXmlString(publicKey);
bool verification = checkRSA.VerifyData(
dataByte,
CryptoConfig.MapNameToOID("SHA512"),
roundtripSignature);
Console.WriteLine("==Verification==");
Console.WriteLine(verification.ToString());
Console.ReadKey();
}
}
}
现在是有趣的部分
如果我使用UTF8编码,我会得到不同长度的字节数组
256是原始尺寸
484是往返票
UTF7也返回不同的大小
256对679
ASCII和Unicode都返回正确的大小256 vs 256
我试过使用
var sb = new StringBuilder();
for (int i = 0; i < signature.Length; i++)
{
sb.Append(signature[i].ToString("x2"));
}
var sb=new StringBuilder();
for(int i=0;i
去拿绳子。然后我使用Encoding.UTF8.GetBytes()方法
这次我得到了以下尺寸:
256对512
如果我从toString()中删除格式,我会得到:
256对670
签名验证始终失败。
如果我使用“签名”而不是roundtripSignature,效果很好
我的问题是:为什么尽管使用了相同的编码类型,我还是得到了不同的字节数组和字符串?这种转换不应该是无损的吗?Unicode不是一个好的选择,因为至少,\0、CR、LF(以及其他控制代码)会把事情搞砸。(有关更多信息,请参阅)
正如@JamesKPolk所说,您需要使用合适的二进制到文本编码。Base64和hex/Base16是最常见的,但也有。加密正在进行打包,因此数据中的重复位是压缩的。因此,在MSB设置为零的情况下使用UTF7将更改文件大小。是的,无论您正在进行何种编码,在过程的开始和结束时,未加密的数据大小都应该相同。您应该能够打开xml文本文件,看看有什么区别可以帮助隔离问题。签名字节不是任何字符集的编码,因此您的方法不可靠。将加密输出转换为字符串的标准方法是base64编码。@JamesKPolk谢谢!就这样。这么简单的解决方案,我却找不到。不知何故,我假设这些集合的每个位组合都有一个字符。