我应该使用MessageDigest来验证在C#中签名的数字签名吗?

huangapple go评论113阅读模式
英文:

Should I use MessageDigest to verify a digital signature that signed in C#?

问题

以下是翻译好的内容:

C#:

  1. static string SignData(string message, RSAParameters privateKey)
  2. {
  3. byte[] signedBytes;
  4. using (var rsa = new RSACryptoServiceProvider())
  5. {
  6. var encoder = new UTF8Encoding();
  7. byte[] originalData = encoder.GetBytes(message);
  8. rsa.ImportParameters(privateKey);
  9. signedBytes = rsa.SignData(originalData, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
  10. rsa.PersistKeyInCsp = false;
  11. }
  12. return Convert.ToBase64String(signedBytes);
  13. }

Java:

  1. static boolean verifySignature512(String message, String sign, PublicKey publicKey) throws Exception {
  2. // MessageDigest digest = MessageDigest.getInstance("SHA-512");
  3. // byte[] contentDigest = digest.digest(message.getBytes(Charset.forName("UTF-8")));
  4. Signature signature = Signature.getInstance("SHA512withRSA");
  5. signature.initVerify(publicKey);
  6. signature.update(message.getBytes(Charset.forName("UTF-8")));
  7. return signature.verify(Base64.getDecoder().decode(sign));
  8. }

请注意,上述内容中的代码片段已经根据你的要求进行了翻译。如果你有任何关于代码部分的问题或需要进一步的帮助,请随时提问。

英文:

I'm new in Java and want to sign some data in c# and verify in Java with RSA and SHA512.

C#:

  1. static string SignData(string message, RSAParameters privateKey)
  2. {
  3. byte[] signedBytes;
  4. using (var rsa = new RSACryptoServiceProvider())
  5. {
  6. var encoder = new UTF8Encoding();
  7. byte[] originalData = encoder.GetBytes(message);
  8. rsa.ImportParameters(privateKey);
  9. signedBytes = rsa.SignData(originalData, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
  10. rsa.PersistKeyInCsp = false;
  11. }
  12. return Convert.ToBase64String(signedBytes);
  13. }

Java:

  1. static boolean verifySignature512(String message, String sign, PublicKey publicKey) throws Exception {
  2. MessageDigest digest = MessageDigest.getInstance("SHA-512");
  3. byte[] contentDigest = digest.digest(message.getBytes(Charset.forName("UTF-8")));
  4. Signature signature = Signature.getInstance("Sha512withRSA");
  5. signature.initVerify(publicKey);
  6. signature.update(contentDigest);
  7. return signature.verify(Base64.getDecoder().decode(sign));
  8. }

I used RSA and public and private keys. Java function always return false with no error or exception.
If I remove MessageDigest like below it starts working, Is it ok and secure?

  1. static boolean verifySignature512(String message, String sign, PublicKey publicKey) throws Exception {
  2. // MessageDigest digest = MessageDigest.getInstance("SHA-512");
  3. // byte[] contentDigest = digest.digest(message.getBytes(Charset.forName("UTF-8")));
  4. Signature signature = Signature.getInstance("Sha512withRSA");
  5. signature.initVerify(publicKey);
  6. signature.update(message.getBytes(Charset.forName("UTF-8")));
  7. return signature.verify(Base64.getDecoder().decode(sign));
  8. }

答案1

得分: 1

以下是翻译好的内容:

C#-code:

  1. using System;
  2. using System.Security.Cryptography;
  3. using System.Text;
  4. class RSACSPSample {
  5. static void Main() {
  6. try {
  7. Console.WriteLine("Should I use MessageDigest to verify a digital signature that signed in C#?");
  8. // 创建UnicodeEncoder以在字节数组和字符串之间进行转换。
  9. ASCIIEncoding ByteConverter = new ASCIIEncoding();
  10. string message = "this is the important message to sign";
  11. // 获取私钥和公钥 ### 示例和不安全的512位RSA密钥对
  12. var privateKey = "<RSAKeyValue><Modulus>mfgthqgvK5P6kP00ojzA68+tGMwjEacduojFSukazKPXrZ8Q5XjzfqgJmDQ3wcWe3hWK92O3z/tmAuN47KA0ZQ==</Modulus><Exponent>AQAB</Exponent><P>8VCRao0hZmIv5gVGFLqOD/7n6TQKlekA96U1QVzimKM=</P><Q>o1bchWA5ddDd59FED37QcrakoTXNoxRspFtsLDKEp1c=</Q><DP>ugF0VUE7wYNlkFP4VPoHjuTZNbRbhHn5uOmrRxqlvyk=</DP><DQ>XoGggC9Hr8pUyo9DIPAP7X+Ny5TU0Vm87m/TK9Ni+2s=</DQ><InverseQ>YqOHEP8dgCvz5Q8nhpQgdrKfdlmjkNAFxKF7j3pm09I=</InverseQ><D>mCpGy/rxS08e5iXn26LRQvvm5UfyLKMNZWmAGk2QF8cRGFB7dds/SI9wGTC9xyOoF4N2kWzYdLx+dYbR9lqwbQ==</D></RSAKeyValue>";
  13. var publicKey = "<RSAKeyValue><Modulus>mfgthqgvK5P6kP00ojzA68+tGMwjEacduojFSukazKPXrZ8Q5XjzfqgJmDQ3wcWe3hWK92O3z/tmAuN47KA0ZQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
  14. // 创建RSACryptoServiceProvider类的新实例
  15. RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider(512);
  16. RSAalg.PersistKeyInCsp = false;
  17. RSAalg.FromXmlString(privateKey);
  18. RSAParameters rsaParameters = RSAalg.ExportParameters(true);
  19. String signedData = SignData(message, rsaParameters);
  20. Console.WriteLine("signedData: " + signedData);
  21. // 使用xml公钥进行验证
  22. RSAalg.FromXmlString(publicKey);
  23. rsaParameters = RSAalg.ExportParameters(false);
  24. bool verifiedData = VerifyData(message, signedData, rsaParameters);
  25. // 验证数据并将结果显示在控制台上。
  26. if (VerifyData(message, signedData, rsaParameters)) {
  27. Console.WriteLine("The data was verified.");
  28. }
  29. else {
  30. Console.WriteLine("The data does not match the signature.");
  31. }
  32. }
  33. catch(ArgumentNullException) {
  34. Console.WriteLine("The data was not signed or verified");
  35. }
  36. }
  37. static string SignData(string message, RSAParameters privateKey)
  38. {
  39. byte[] signedBytes;
  40. using (var rsa = new RSACryptoServiceProvider())
  41. {
  42. var encoder = new UTF8Encoding();
  43. byte[] originalData = encoder.GetBytes(message);
  44. rsa.ImportParameters(privateKey);
  45. signedBytes = rsa.SignData(originalData, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
  46. rsa.PersistKeyInCsp = false;
  47. }
  48. return Convert.ToBase64String(signedBytes);
  49. }
  50. public static bool VerifyData(string message, string signedData, RSAParameters rsaParameters)
  51. {
  52. byte[] messageBytes;
  53. byte[] signedBytes;
  54. using (var rsa = new RSACryptoServiceProvider())
  55. try
  56. {
  57. var encoder = new UTF8Encoding();
  58. messageBytes = encoder.GetBytes(message);
  59. signedBytes = Convert.FromBase64String(signedData);
  60. rsa.ImportParameters(rsaParameters);
  61. return rsa.VerifyData(messageBytes, new SHA1CryptoServiceProvider(), signedBytes);
  62. }
  63. catch(CryptographicException e) {
  64. Console.WriteLine(e.Message);
  65. return false;
  66. }
  67. }
  68. }

Java-code:

  1. import java.nio.charset.StandardCharsets;
  2. import java.security.*;
  3. import java.security.spec.X509EncodedKeySpec;
  4. import java.util.Base64;
  5. public class MainSha1 {
  6. public static void main(String[] args) throws GeneralSecurityException {
  7. System.out.println("Should I use MessageDigest to verify a digital signature that signed in C#?");
  8. String message = "this is the important message to sign";
  9. // 这是一个示例和不安全的RSA 512位密钥
  10. String publicKeyPem = "-----BEGIN PUBLIC KEY-----\n" +
  11. "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJn4LYaoLyuT+pD9NKI8wOvPrRjMIxGn\n" +
  12. "HbqIxUrpGsyj162fEOV4836oCZg0N8HFnt4Vivdjt8/7ZgLjeOygNGUCAwEAAQ==\n" +
  13. "-----END PUBLIC KEY-----";
  14. String signedData = "HS4qvrXpqu97me7yDt9lWXp+QLjKMO8FY4kiUiGhMhi6KmXQXCtmcUWSbg0i+LXv7u5ueRiQNeBnu6UCbPhZLg==";
  15. String rsaInstanceString = "SHA1withRSA";
  16. System.out.println("RSA instance: " + rsaInstanceString);
  17. PublicKey publicKey = getPublicKeyFromString(publicKeyPem);
  18. boolean verifyData = verifyRsa(publicKey, rsaInstanceString, message.getBytes(StandardCharsets.UTF_8), Base64.getDecoder().decode(signedData));
  19. if (verifyData == true) {
  20. System.out.println("The data was verified.");
  21. } else {
  22. System.out.println("The data could NOT get verified.");
  23. }
  24. }
  25. public static PublicKey getPublicKeyFromString(String key) throws GeneralSecurityException {
  26. String publicKeyPEM = key;
  27. publicKeyPEM = publicKeyPEM.replace("-----BEGIN PUBLIC KEY-----", "");
  28. publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");
  29. publicKeyPEM = publicKeyPEM.replaceAll("[\\r\\n]+", "");
  30. byte[] encoded = Base64.get
  31. <details>
  32. <summary>英文:</summary>
  33. The signature verification on Java-side has to fail as you are using different hashing algorithms on both sides.
  34. In C# you are using SHA1 (&#39;HashAlgorithmName.SHA1&#39;) and the Java-part is using SHA512 (&#39;Signature signature = Signature.getInstance(&quot;Sha512withRSA&quot;);&#39;).
  35. The following code is using SHA1 as hash algorithm but you can easily change this (on all codelines :-) to SHA256 or SHA512.
  36. The C#-code verifies the signature with the public key, the same public key (encoded as PEM) is used in the Java-code
  37. for verification only.
  38. **Security warning: My example codes are using UNSECURE 512-bit RSA-keys that should not used in production.
  39. There is not proper exception handling and you are using the padding &#39;RSASignaturePadding.Pkcs1&#39; which should
  40. NOT used anymore as well.**
  41. This is the output of my C#-code:
  42. Should I use MessageDigest to verify a digital signature that signed in C#?
  43. signedData: mU2bcCMEhG13xG9sKwhaA//dnw2+rbLkwz2737cNU5kb2EBenJIEJ+bA596XccCVKUKPanxMUFoVw2fl8HhCNw==
  44. The data was verified.
  45. That&#39;s the Java-output:
  46. RSA instance: SHA1withRSA
  47. The data was verified.
  48. C#-code:
  49. using System;
  50. using System.Security.Cryptography;
  51. using System.Text;
  52. class RSACSPSample {
  53. static void Main() {
  54. try {
  55. Console.WriteLine(&quot;Should I use MessageDigest to verify a digital signature that signed in C#?&quot;);
  56. // Create a UnicodeEncoder to convert between byte array and string.
  57. ASCIIEncoding ByteConverter = new ASCIIEncoding();
  58. string message = &quot;this is the important message to sign&quot;;
  59. // get private and public key ### SAMPLE and UNSECURE 512 bit RSA keypair
  60. var privateKey = &quot;&lt;RSAKeyValue&gt;&lt;Modulus&gt;mfgthqgvK5P6kP00ojzA68+tGMwjEacduojFSukazKPXrZ8Q5XjzfqgJmDQ3wcWe3hWK92O3z/tmAuN47KA0ZQ==&lt;/Modulus&gt;&lt;Exponent&gt;AQAB&lt;/Exponent&gt;&lt;P&gt;8VCRao0hZmIv5gVGFLqOD/7n6TQKlekA96U1QVzimKM=&lt;/P&gt;&lt;Q&gt;o1bchWA5ddDd59FED37QcrakoTXNoxRspFtsLDKEp1c=&lt;/Q&gt;&lt;DP&gt;ugF0VUE7wYNlkFP4VPoHjuTZNbRbhHn5uOmrRxqlvyk=&lt;/DP&gt;&lt;DQ&gt;XoGggC9Hr8pUyo9DIPAP7X+Ny5TU0Vm87m/TK9Ni+2s=&lt;/DQ&gt;&lt;InverseQ&gt;YqOHEP8dgCvz5Q8nhpQgdrKfdlmjkNAFxKF7j3pm09I=&lt;/InverseQ&gt;&lt;D&gt;mCpGy/rxS08e5iXn26LRQvvm5UfyLKMNZWmAGk2QF8cRGFB7dds/SI9wGTC9xyOoF4N2kWzYdLx+dYbR9lqwbQ==&lt;/D&gt;&lt;/RSAKeyValue&gt;&quot;;
  61. var publicKey = &quot;&lt;RSAKeyValue&gt;&lt;Modulus&gt;mfgthqgvK5P6kP00ojzA68+tGMwjEacduojFSukazKPXrZ8Q5XjzfqgJmDQ3wcWe3hWK92O3z/tmAuN47KA0ZQ==&lt;/Modulus&gt;&lt;Exponent&gt;AQAB&lt;/Exponent&gt;&lt;/RSAKeyValue&gt;&quot;;
  62. // Create a new instance of the RSACryptoServiceProvider class
  63. RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider(512);
  64. RSAalg.PersistKeyInCsp = false;
  65. RSAalg.FromXmlString(privateKey);
  66. RSAParameters rsaParameters = RSAalg.ExportParameters(true);
  67. String signedData = SignData(message, rsaParameters);
  68. Console.WriteLine(&quot;signedData: &quot; + signedData);
  69. // verify with xml-public key
  70. RSAalg.FromXmlString(publicKey);
  71. rsaParameters = RSAalg.ExportParameters(false);
  72. bool verifiedData = VerifyData(message, signedData, rsaParameters);
  73. // Verify the data and display the result to the
  74. // console.
  75. if (VerifyData(message, signedData, rsaParameters)) {
  76. Console.WriteLine(&quot;The data was verified.&quot;);
  77. }
  78. else {
  79. Console.WriteLine(&quot;The data does not match the signature.&quot;);
  80. }
  81. }
  82. catch(ArgumentNullException) {
  83. Console.WriteLine(&quot;The data was not signed or verified&quot;);
  84. }
  85. }
  86. static string SignData(string message, RSAParameters privateKey)
  87. {
  88. byte[] signedBytes;
  89. using (var rsa = new RSACryptoServiceProvider())
  90. {
  91. var encoder = new UTF8Encoding();
  92. byte[] originalData = encoder.GetBytes(message);
  93. rsa.ImportParameters(privateKey);
  94. signedBytes = rsa.SignData(originalData, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
  95. rsa.PersistKeyInCsp = false;
  96. }
  97. return Convert.ToBase64String(signedBytes);
  98. }
  99. public static bool VerifyData(string message, string signedData, RSAParameters rsaParameters)
  100. {
  101. byte[] messageBytes;
  102. byte[] signedBytes;
  103. using (var rsa = new RSACryptoServiceProvider())
  104. try
  105. {
  106. var encoder = new UTF8Encoding();
  107. messageBytes = encoder.GetBytes(message);
  108. signedBytes = Convert.FromBase64String(signedData);
  109. rsa.ImportParameters(rsaParameters);
  110. return rsa.VerifyData(messageBytes, new SHA1CryptoServiceProvider(), signedBytes);
  111. }
  112. catch(CryptographicException e) {
  113. Console.WriteLine(e.Message);
  114. return false;
  115. }
  116. }
  117. }
  118. Java-code:
  119. import java.nio.charset.StandardCharsets;
  120. import java.security.*;
  121. import java.security.spec.X509EncodedKeySpec;
  122. import java.util.Base64;
  123. public class MainSha1 {
  124. public static void main(String[] args) throws GeneralSecurityException {
  125. System.out.println(&quot;Should I use MessageDigest to verify a digital signature that signed in C#?&quot;);
  126. String message = &quot;this is the important message to sign&quot;;
  127. // this is a SAMPLE and UNSECURE RSA 512 bit key
  128. String publicKeyPem = &quot;-----BEGIN PUBLIC KEY-----\n&quot; +
  129. &quot;MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJn4LYaoLyuT+pD9NKI8wOvPrRjMIxGn\n&quot; +
  130. &quot;HbqIxUrpGsyj162fEOV4836oCZg0N8HFnt4Vivdjt8/7ZgLjeOygNGUCAwEAAQ==\n&quot; +
  131. &quot;-----END PUBLIC KEY-----&quot;;
  132. String signedData = &quot;HS4qvrXpqu97me7yDt9lWXp+QLjKMO8FY4kiUiGhMhi6KmXQXCtmcUWSbg0i+LXv7u5ueRiQNeBnu6UCbPhZLg==&quot;;
  133. String rsaInstanceString = &quot;SHA1withRSA&quot;;
  134. System.out.println(&quot;RSA instance: &quot; + rsaInstanceString);
  135. PublicKey publicKey = getPublicKeyFromString(publicKeyPem);
  136. boolean verifyData = verifyRsa(publicKey, rsaInstanceString, message.getBytes(StandardCharsets.UTF_8), Base64.getDecoder().decode(signedData));
  137. if (verifyData = true) {
  138. System.out.println(&quot;The data was verified.&quot;);
  139. } else {
  140. System.out.println(&quot;The data could NOT get verified.&quot;);
  141. }
  142. }
  143. public static PublicKey getPublicKeyFromString(String key) throws GeneralSecurityException {
  144. String publicKeyPEM = key;
  145. publicKeyPEM = publicKeyPEM.replace(&quot;-----BEGIN PUBLIC KEY-----&quot;, &quot;&quot;);
  146. publicKeyPEM = publicKeyPEM.replace(&quot;-----END PUBLIC KEY-----&quot;, &quot;&quot;);
  147. publicKeyPEM = publicKeyPEM.replaceAll(&quot;[\\r\\n]+&quot;, &quot;&quot;);
  148. byte[] encoded = Base64.getDecoder().decode(publicKeyPEM);
  149. KeyFactory kf = KeyFactory.getInstance(&quot;RSA&quot;);
  150. PublicKey pubKey = (PublicKey) kf.generatePublic(new X509EncodedKeySpec(encoded));
  151. return pubKey;
  152. }
  153. public static Boolean verifyRsa(PublicKey publicKey, String rsaInstanceString, byte[] messageByte,
  154. byte[] signatureByte) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
  155. Signature publicSignature = Signature.getInstance(rsaInstanceString);
  156. publicSignature.initVerify(publicKey);
  157. publicSignature.update(messageByte);
  158. return publicSignature.verify(signatureByte);
  159. }
  160. }
  161. </details>

huangapple
  • 本文由 发表于 2020年8月27日 20:25:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/63615966.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定