2017-04-11 232 views
0

我的問題與2011年的一個表格Signing and verifying signatures with RSA C#非常相似。儘管如此,當我比較簽名數據和原始消息時,我也會失敗。請指出我的錯誤。C#使用RSA簽名和驗證簽名。編碼問題

代碼:

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

簽名方法:

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

驗證方法:

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

基本上問題是與串爲byte []編碼。我遇到了與ASCIIEncoding和UTF8Encoding相同的問題。

預先感謝您!

回答

2

您不能在編碼消息上使用ASCIIEncoding,因爲它包含無效ASCII字符的字節。存儲編碼消息的典型方法是使用base64字符串。

SignData,使用以下的字節數組編碼爲字符串:

return Convert.ToBase64String(signedBytes); 

VerifyData,使用下面的字符串後面進行解碼,以相同的字節數組:

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

感謝您的及時答覆!但是,我得到「System.FormatException:」輸入不是有效的Base-64字符串,因爲它包含非基本64字符,多於兩個填充字符或填充字符中的非法字符。'「當我使用FromBase64String爲消息「」2017-04-10T09:37:35.351Z「」。 –

+1

在驗證之前是否有任何事情發生在字符串上?我用上面的2個更改運行了你的發佈代碼,它工作。 – msitt

+0

你是對的!我的糟糕之處在於,我還試圖在簽名之前對原始數據的Base64字符串執行字符串。 –