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;
}


