c# - rsacryptoserviceprovider signdata
Firmando y verificando firmas con RSA C# (1)
Tu problema está al comienzo del método 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
...
Por algún motivo, FromBase64String
a FromBase64String
lugar de UTF8Encoding.GetBytes
.
Recientemente publiqué sobre problemas con el cifrado de datos grandes con RSA, finalmente he terminado con eso y ahora paso a implementar la firma con la clave privada de un usuario y verificar con la clave pública correspondiente. Sin embargo, cada vez que comparo los datos firmados y el mensaje original, básicamente obtengo un falso. Espero que algunos de ustedes puedan ver lo que estoy haciendo mal.
Aquí está el código:
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);
}
Entonces ese es el primer paso, para firmar los datos, luego paso a verificar los datos:
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;
}
Y aquí está el cliente de prueba:
public static void Main(string[] args)
{
PublicKeyInfrastructure pki = new PublicKeyInfrastructure();
Cryptograph crypto = new Cryptograph();
RSAParameters privateKey = crypto.GenerateKeys("[email protected]");
const string PlainText = "This is really sent by me, really!";
RSAParameters publicKey = crypto.GetPublicKey("[email protected]");
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);
}
¿Me estoy perdiendo un paso aquí? De acuerdo con la API de criptografía y los ejemplos allí, no debería calcular manualmente ningún hash, ya que proporciono el algoritmo dentro de la llamada al método.
Cualquier ayuda será apreciada.