這兩個方法和SignData和VerifyData是等價的,只不過傳入的參數是雜湊值而不是未經處理資料。也就是說SignData中RSA加密的雜湊值函數是自己計算的。而SignHash需要我們來計算然後傳入參數。
唯一一點需要注意的是,SignHash(和VerifyHash)方法需指定的雜湊演算法雖然是字串對象,但其是以雜湊演算法標識符 (OID) 的形式。所以需要另外一個方法就是:CryptoConfig.MapNameToOID來專門的一個雜湊演算法類型字串轉換成雜湊演算法標識符 (OID) 的形式。
代碼:
//+ using using System.Security.Cryptography
using (var rsa = new RSACryptoServiceProvider())
using (var sha1 = SHA1.Create())
{
//未經處理資料
var data = new byte[] { 1, 2, 3 };
//計算雜湊值
var hash = sha1.ComputeHash(data);
//用SignHash,注意使用CryptoConfig.MapNameToOID
var sigHash = rsa.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));
//用SignData,直接傳入資料(函數內部會計算雜湊值)
var sigData = rsa.SignData(data, typeof(SHA1));
//輸出兩個簽名資料
Console.WriteLine(BitConverter.ToString(sigHash));
Console.WriteLine(BitConverter.ToString(sigData));
//驗證
Console.WriteLine(rsa.VerifyHash(hash, "SHA1", sigHash));
Console.WriteLine(rsa.VerifyData(data, typeof(SHA1), sigData));
}
輸出:
7C-9B-6C-77-DB-A1-22-81-34-03-8F-D7-2D-CE-ED-CB-F0-A9-3B-4F-E7-9C-B7-66-C7-14-01
-55-6D-E0-48-DC-38-54-1A-90-6F-67-BE-8C-85-93-5E-4C-E7-41-DD-81-85-3F-4C-B6-1E-8
8-70-48-3F-B6-FC-7A-33-36-13-B1-38-43-0C-39-98-EC-43-50-DD-B8-51-FB-BF-A8-1D-38-
13-76-29-B5-B3-04-09-18-B5-F5-D1-F3-6E-E6-DB-FE-37-A5-7B-A8-98-00-27-0A-98-6B-A9
-69-97-D8-0C-F7-1D-01-AE-89-8C-BE-FE-86-8C-81-24-AA-9D-8A-22-84
7C-9B-6C-77-DB-A1-22-81-34-03-8F-D7-2D-CE-ED-CB-F0-A9-3B-4F-E7-9C-B7-66-C7-14-01
-55-6D-E0-48-DC-38-54-1A-90-6F-67-BE-8C-85-93-5E-4C-E7-41-DD-81-85-3F-4C-B6-1E-8
8-70-48-3F-B6-FC-7A-33-36-13-B1-38-43-0C-39-98-EC-43-50-DD-B8-51-FB-BF-A8-1D-38-
13-76-29-B5-B3-04-09-18-B5-F5-D1-F3-6E-E6-DB-FE-37-A5-7B-A8-98-00-27-0A-98-6B-A9
-69-97-D8-0C-F7-1D-01-AE-89-8C-BE-FE-86-8C-81-24-AA-9D-8A-22-84
True
True
兩種方法可以得到同樣的簽名資料的。