大家!
我正在尝试用C#对一些数据进行数字签名。一切都没有错误,但当我想看到RSACryptoServiceProvider.SignHash的结果时,我得到了一些奇怪的结果。
这是我的代码:
System.Security.Cryptography.X509Certificates.X509Store store = new System.Security.Cryptography.X509Certificates.X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certCollection = store.Certificates.Find(X509FindType.FindBySubjectName, "SOME NAME", true);
X509Certificate2Enumerator enumerator = certCollection.GetEnumerator();
X509Certificate2 x509 = null;
while (enumerator.MoveNext()){
x509 = enumerator.Current;
}
store.Close();
RSACryptoServiceProvider csp = null;
csp = (RSACryptoServiceProvider)x509.PrivateKey;
if (csp == null){
throw new Exception("Valid certificate was not found");
}
string sTestText = "SomeTestData";
System.Text.ASCIIEncoding encoding=new System.Text.ASCIIEncoding();
SHA1Managed sha1 = new SHA1Managed();
ASCIIEncoding encoding2 = new System.Text.ASCIIEncoding();
byte[] data = encoding2.GetBytes(sTestText);
byte[] hash = sha1.ComputeHash(data);
Byte[] baSignedHash = csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));
string sSignedHash = System.Text.ASCIIEncoding.ASCII.GetString(baSignedHAsh);
Console.WriteLine("sSignedHash=" + sSignedHash );
我收到这个文字: sSignedHash =?H↨C^↑X X ???????????????????????????????????????????????????? 2 p♠♥{♫?? [I↔?????◄??;?!?????}????Sx☺>有VN I6☻'??▲F 14吨@ ?E?↕??►??►k?? v?'☻GX ??} x @ ???)?? F?7TP?♂& ??
我尝试了不同的编码(UTF8等),但没有运气。 enyone知道可能是什么问题吗?
答案 0 :(得分:2)
enyone知道可能出现什么问题吗?
是。您正在尝试将不透明的二进制数据视为文本。不是。
您可以获得十六进制表示:
string text = BitConverter.ToString(baSignedHash);
或base-64表示:
string text = Convert.ToBase64String(baSignedHash);
理解“实际编码的文本数据的二进制数据”(即Encoding.GetString
所在的位置)和“非文本的二进制数据”(例如图像数据,可执行文件)之间的区别非常重要,加密数据,压缩数据)。
答案 1 :(得分:1)
您不应使用任何文本编码,因为哈希不代表任何文本。它只是一堆字节。
您应该使用十六进制编码或Base64编码将哈希转换为可读的内容。
Hex的优点是散列的每个字节对应于输出的两个字符。
string sSignedHash = BitConverter.ToString(baSignedHash).Replace("-", "");
Base64的优势在于它更短。
string sSignedHash = Convert.ToBase64String(baSignedHash);
要对输入文本进行编码,建议您使用new Utf8Encoding(false, true)
。这不会发出BOM,它会在遇到无效输入时抛出异常,而不是静默输出损坏的数据。