3,数字签名和验证
私钥签名数据m时,先对m进行hash计算,得到计算结果h。然后将h使用私钥加密,得到加密后的密文s即为签名。
公钥验证签名s时,先将m进行hash计算,得到计算结果h。然后使用公钥解密s得到结果h’。如果h==h’即验证成功,否则验证失败。
在某些情况下,也会使用公钥签名->私钥验证。原理和私钥签名->公钥验证一样。
下面是私钥签名->公钥验证的实现。
public static byte[] Sign(byte[] data, RSAPublicKey publicKey, HashAlgorithm hash) { if (data == null) { throw new ArgumentNullException("data"); } if (publicKey == null) { throw new ArgumentNullException("publicKey"); } if (hash == null) { throw new ArgumentNullException("hash"); } byte[] hashData = hash.ComputeHash(data); byte[] signature = Encrypt(hashData, publicKey); return signature; } public static bool Verify(byte[] data, RSAPrivateKey privateKey, HashAlgorithm hash, byte[] signature) { if (data == null) { throw new ArgumentNullException("data"); } if (privateKey == null) { throw new ArgumentNullException("privateKey"); } if (hash == null) { throw new ArgumentNullException("hash"); } if (signature == null) { throw new ArgumentNullException("signature"); } byte[] hashData = hash.ComputeHash(data); byte[] signatureHashData = Decrypt(signature, privateKey); if (signatureHashData != null && signatureHashData.Length == hashData.Length) { for (int i = 0; i < signatureHashData.Length; i++) { if (signatureHashData[i] != hashData[i]) { return false; } } return true; } return false; } 下面是公钥签名->私钥验证的实现。public static byte[] Sign(byte[] data, RSAPrivateKey privateKey, HashAlgorithm hash) { if (data == null) { throw new ArgumentNullException("data"); } if (privateKey == null) { throw new ArgumentNullException("privateKey"); } if (hash == null) { throw new ArgumentNullException("hash"); } byte[] hashData = hash.ComputeHash(data); byte[] signature = Encrypt(hashData, privateKey); return signature; } public static bool Verify(byte[] data, RSAPublicKey publicKey, HashAlgorithm hash, byte[] signature) { if (data == null) { throw new ArgumentNullException("data"); } if (publicKey == null) { throw new ArgumentNullException("publicKey"); } if (hash == null) { throw new ArgumentNullException("hash"); } if (signature == null) { throw new ArgumentNullException("signature"); } byte[] hashData = hash.ComputeHash(data); byte[] signatureHashData = Decrypt(signature, publicKey); if (signatureHashData != null && signatureHashData.Length == hashData.Length) { for (int i = 0; i < signatureHashData.Length; i++) { if (signatureHashData[i] != hashData[i]) { return false; } } return true; } return false; }