2017-04-11 1 views
0

Ma question est assez similaire à celle de 2011, Signing and verifying signatures with RSA C#. Néanmoins, je deviens également faux quand je compare les données signées et le message original. S'il vous plaît pointez sur mon erreur.C# Signature et vérification des signatures avec RSA. Encoding issue

code:

public static void Main(string[] args) 
    {    

     //Generate a public/private key pair. 
     RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); 

     //Save the public key information to an RSAParameters structure. 
     RSAParameters RSAPublicKeyInfo = RSA.ExportParameters(false); 
     RSAParameters RSAPrivateKeyInfo = RSA.ExportParameters(true);  

     string message = "2017-04-10T09:37:35.351Z"; 

     string signedMessage = SignData(message, RSAPrivateKeyInfo); 

     bool success = VerifyData(message, signedMessage, RSAPublicKeyInfo); 

     Console.WriteLine($"success {success}"); 

     Console.ReadLine(); 
    } 

procédé de signature:

public static string SignData(string message, RSAParameters privateKey) 
    { 
     ASCIIEncoding byteConverter = new ASCIIEncoding(); 

     byte[] signedBytes; 

     using (var rsa = new RSACryptoServiceProvider()) 
     { 
      // Write the message to a byte array using ASCII as the encoding. 
      byte[] originalData = byteConverter.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 byte array back to a string message 
     return byteConverter.GetString(signedBytes); 
    } 

Méthode de vérification:

public static bool VerifyData(string originalMessage, string signedMessage, RSAParameters publicKey) 
    { 
     bool success = false; 
     using (var rsa = new RSACryptoServiceProvider()) 
     { 
      ASCIIEncoding byteConverter = new ASCIIEncoding(); 

      byte[] bytesToVerify = byteConverter.GetBytes(originalMessage); 
      byte[] signedBytes = byteConverter.GetBytes(signedMessage); 

      try 
      { 
       rsa.ImportParameters(publicKey); 

       success = rsa.VerifyData(bytesToVerify, CryptoConfig.MapNameToOID("SHA512"), signedBytes); 
      } 
      catch (CryptographicException e) 
      { 
       Console.WriteLine(e.Message); 
      } 
      finally 
      { 
       rsa.PersistKeyInCsp = false; 
      } 
     } 
     return success; 
    } 

Fondamentalement, le problème est lié à la chaîne de byte [] codant. J'ai le même problème avec ASCIIEncoding et avec UTF8Encoding.

Merci d'avance!

Répondre

2

Vous ne pouvez pas utiliser ASCIIEncoding sur le message codé car il contient des octets qui sont des caractères ASCII non valides. La façon typique de stocker le message codé est dans une chaîne base64.

Dans SignData, utiliser ce qui suit pour coder le tableau d'octets dans une chaîne:

return Convert.ToBase64String(signedBytes); 

et en VerifyData, en utilisant ce qui suit pour décoder la chaîne de retour au même tableau d'octets:

byte[] signedBytes = Convert.FromBase64String(signedMessage); 
+0

Merci de votre réponse rapide! Cependant, je reçois "System.FormatException: 'L'entrée n'est pas une chaîne Base-64 valide car elle contient un caractère non-base 64, plus de deux caractères de remplissage, ou un caractère illégal parmi les caractères de remplissage." "Quand j'utilise FromBase64String pour le message "" 2017-04-10T09: 37: 35.351Z "". –

+1

Y at-il quelque chose qui arrive à la chaîne avant de la vérifier? J'ai couru votre code posté avec les 2 changements ci-dessus et cela a fonctionné. – msitt

+0

vous avez raison! Mon mauvais était que j'essayais aussi d'effectuer la chaîne à la chaîne Base64 des données originales avant de signer. –