RSA and PublicKey interop with dotnet

前端 未结 1 1354
渐次进展
渐次进展 2021-01-28 12:22

Hi I am using code from this link, Can you let me know why signature is verify is not working?

Java signer is using BouncyCastleProvider with SHA1withRSA

相关标签:
1条回答
  • 2021-01-28 13:20

    There's a couple problems problems here.

    String signature = "770bb ... 1c7ca";
    ...
    byte[] expectedSig = System.Convert.FromBase64String(signature);
    

    You're Base64 decoding the signature, but it's not Base64 encoded, it's Hex encoded.

    The second problem is in the DecodeX509PublicKey methods (which admittedly is my mistake because I provided this code in another answer.) The specific problem lines are

    Array.Reverse(modulus); //convert to big-endian
    

    and

    Array.Reverse(exponent); //convert to big-endian
    

    I repeatedly read that the ASN.1 and the .Net API use opposite endieness for their keys, and so I was under the impression that the endieness needed to be reversed to account for this. (I really should have done a test like your signature verification to be sure, rather than just looking at the key values in memory >.<) Regardless, remove these lines, fix the encoding problem, and your signature will verify properly (successfully tested using your sample data as well as my own).

    Also, this line in your sign method isn't quite right:

    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    

    By the time you get to that point in the code, the signer object has already been instantiated using the default provider. Also, you don't need to be adding the Bouncy Castle provider each time you want to sign some data, it will only actually add the provider the first time you make this call and will ignore it for all subsequent calls.

    Further, the signer object is declaired static, but your usage of it is not thread safe.

    What you more likely want to do is add the provider in the static block and then instantiate the signer explicitly using the Bouncy Castle provider. If you don't explicitly specify Bouncy Castle as the provider (or add Bouncy Castle as the highest priority using insertProviderAt), the default provider will be used instead.

    static {
        try {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    ...
    
    String signed = null;
    try {
        java.security.Signature signer = java.security.Signature.getInstance("SHA1withRSA", "BC");
        byte[] data = clearText.getBytes("UTF-8");
        signer.initSign(getPrivateKey());
    
    ...
    
    0 讨论(0)
提交回复
热议问题