title: Signing and verifying signatures with RSA C#
body: <p>I recently posted about issues with encrypting large data with RSA, I am finally done with that and now I am moving on to implementing signing with a user's private key and verifying with the corresponding public key. However, whenever I compare the signed data and the original message I basically just get false returned. I am hoping some of your could see what I am doing wrong.</p>
  
  <p>Here is the code:</p>
  
  <pre><code>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);
      }
  </code></pre>
  
  <p>So that is the first step, to sign the data, next I move on to verifying the data:</p>
  
  <pre><code>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;
      }
  </code></pre>
  
  <p>And here is the test client:</p>
  
  <pre><code>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);
  
      }
  </code></pre>
  
  <p>Am I missing a step here? According to the Cryptography API and the examples there, I shouldn't manually compute any hashes, since I supply the algorithm within the method call itself.</p>
  
  <p>Any help will be greatly appreciated.</p>