我最近发布了有关使用RSA加密大数据的问题,我终于完成了,现在我继续使用用户的私钥实现签名,并使用相应的公钥进行验证。但是,每当我比较签名数据和原始消息时,我基本上只会得到false返回。我希望你们中的一些人可以看到我做错了什么。
这是代码:
public static string SignData(string message, RSAParameters privateKey) { //// The array to store the signed message in bytes byte[] signedBytes; using (var rsa = new RSACryptoServiceProvider()) { //// Write the message to a byte array using UTF8 as the encoding. var encoder = new UTF8Encoding(); byte[] originalData = encoder.GetBytes(message); try { //// Import the private key used for signing the message rsa.ImportParameters(privateKey); //// Sign the data, using SHA512 as the hashing algorithm signedBytes = rsa.SignData(originalData, CryptoConfig.MapNameToOID("SHA512")); } catch (CryptographicException e) { Console.WriteLine(e.Message); return null; } finally { //// Set the keycontainer to be cleared when rsa is garbage collected. rsa.PersistKeyInCsp = false; } } //// Convert the a base64 string before returning return Convert.ToBase64String(signedBytes); }
所以这是第一步,对数据进行签名,接下来我继续验证数据:
public static bool VerifyData(string originalMessage, string signedMessage, RSAParameters publicKey) { bool success = false; using (var rsa = new RSACryptoServiceProvider()) { byte[] bytesToVerify = Convert.FromBase64String(originalMessage); byte[] signedBytes = Convert.FromBase64String(signedMessage); try { rsa.ImportParameters(publicKey); SHA512Managed Hash = new SHA512Managed(); byte[] hashedData = Hash.ComputeHash(signedBytes); success = rsa.VerifyData(bytesToVerify, CryptoConfig.MapNameToOID("SHA512"), signedBytes); } catch (CryptographicException e) { Console.WriteLine(e.Message); } finally { rsa.PersistKeyInCsp = false; } } return success; }
这是测试客户端:
public static void Main(string[] args) { PublicKeyInfrastructure pki = new PublicKeyInfrastructure(); Cryptograph crypto = new Cryptograph(); RSAParameters privateKey = crypto.GenerateKeys("email@email.com"); const string PlainText = "This is really sent by me, really!"; RSAParameters publicKey = crypto.GetPublicKey("email@email.com"); string encryptedText = Cryptograph.Encrypt(PlainText, publicKey); Console.WriteLine("This is the encrypted Text:" + "\n " + encryptedText); string decryptedText = Cryptograph.Decrypt(encryptedText, privateKey); Console.WriteLine("This is the decrypted text: " + decryptedText); string messageToSign = encryptedText; string signedMessage = Cryptograph.SignData(messageToSign, privateKey); //// Is this message really, really, REALLY sent by me? bool success = Cryptograph.VerifyData(messageToSign, signedMessage, publicKey); Console.WriteLine("Is this message really, really, REALLY sent by me? " + success); }
我在这里错过了一步吗?根据密码学API和那里的示例,我不应该手动计算任何哈希,因为我在方法调用本身中提供了算法。
任何帮助将不胜感激。
您的问题是VerifyData方法的开始:
VerifyData
public static bool VerifyData(string originalMessage, string signedMessage, RSAParameters publicKey) { bool success = false; using (var rsa = new RSACryptoServiceProvider()) { //Don't do this, do the same as you did in SignData: //byte[] bytesToVerify = Convert.FromBase64String(originalMessage); var encoder = new UTF8Encoding(); byte[] bytesToVerify = encoder.GetBytes(originalMessage); byte[] signedBytes = Convert.FromBase64String(signedMessage); try ...
由于某些原因,您切换到FromBase64String而不是UTF8Encoding.GetBytes。
FromBase64String
UTF8Encoding.GetBytes