简体   繁体   中英

Fail to match SHA256withRSA signature from Java on .Net c#

I have some code in Java that successfully verifies and sign messages with SHA256withRSA. However when I try to verify the same data with my c# code, I get a different signature and verification of the signature fails. As the SHA values match, i figure it not related to codepage. I tried multiple ways to figure this one out, but is yet to fail, so any ideas is more than welcome.

import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.X509EncodedKeySpec;
import java.io.*;
import java.util.*;
import java.security.*;
import java.util.Base64;
import java.lang.*;
import java.nio.charset.*;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMException;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;

public class Main {
    public static void main(String[] args) throws Exception {
        String privatePem = "c:\\Lab\\Cert\\private.pem";
        String publicPem = "C:\\Lab\\Cert\\public.pem";
        String datafile = "C:\\Lab\\Cert\\data.txt";

        byte[] buf = Files.readAllBytes(Paths.get(datafile));
        String message = new String(buf, StandardCharsets.UTF_8);

        System.out.println("-----------------------------------------------------------------------------------------------------------------------------------------");
        System.out.println("Message to sign:");
        System.out.println(message);
        System.out.println("-----------------------------------------------------------------------------------------------------------------------------------------");

        PrivateKey privateKey = PrivateKeyReader(privatePem).getPrivate();
        PublicKey publicKey = get(publicPem);

        // Get SHA-256
        byte[] messageAsByte = message.getBytes(Charset.forName( "UTF-8" ));
        byte[] sha256OfMessage = digestSha256(messageAsByte);
        byte[] sha512OfMessage = digestSha512(messageAsByte);
        byte[] base64encodedSha256 = Base64.getEncoder().encode(sha256OfMessage);
         byte[] base64encodedSha512 = Base64.getEncoder().encode(sha512OfMessage);
        String Sha256ContentDigest = new String(base64encodedSha256, StandardCharsets.UTF_8);
        String Sha512ContentDigest = new String(base64encodedSha512, StandardCharsets.UTF_8);

        byte[] signature256 = generateSignature256(messageAsByte, privateKey);
        String sig25664 = Base64.getEncoder().encodeToString(signature256);
        System.out.println("X-Content-Digest: SHA256 " + Sha256ContentDigest);
        System.out.println("X-Signature: RSA-SHA256 " + sig25664);
        System.out.println("-----------------------------------------------------------------------------------------------------------------------------------------");

        byte[] signature512 = generateSignature512(messageAsByte, privateKey);
        String sig51264 = Base64.getEncoder().encodeToString(signature512);
        System.out.println("X-Content-Digest: SHA512 " + Sha512ContentDigest);
        System.out.println("X-Signature: RSA-SHA512 " + sig51264);
        System.out.println("-----------------------------------------------------------------------------------------------------------------------------------------");

        System.out.println("Signature verification SHA256: " + verifySignature256(messageAsByte, sha256OfMessage, signature256, publicKey));
        System.out.println("Signature verification SHA512: " + verifySignature512(messageAsByte, sha512OfMessage, signature512, publicKey));
        System.out.println("-----------------------------------------------------------------------------------------------------------------------------------------");
    }

    private static KeyPair PrivateKeyReader(String keyPath) {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(keyPath));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Security.addProvider(new BouncyCastleProvider());
        PEMParser pp = new PEMParser(br);
        PEMKeyPair pemKeyPair = null;
        try {
            pemKeyPair = (PEMKeyPair) pp.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            KeyPair kp = new JcaPEMKeyConverter().getKeyPair(pemKeyPair);
            return kp;
        } catch (PEMException e) {
            e.printStackTrace();
        }
        try {
            pp.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] generateSignature256(byte[] requestMessage, PrivateKey privateKey) throws Exception {
        byte[] contentDigest = digestSha256(requestMessage);

        Signature signature = Signature.getInstance("Sha256withRSA");
        signature.initSign(privateKey);
        signature.update(contentDigest);
        return signature.sign();
    }

    public static byte[] generateSignature512(byte[] requestMessage, PrivateKey privateKey) throws Exception {
        byte[] contentDigest = digestSha512(requestMessage);

        Signature signature = Signature.getInstance("Sha512withRSA");
        signature.initSign(privateKey);
        signature.update(contentDigest);
        return signature.sign();
    }

    public static boolean verifySignature256(byte[] requestMessage, byte[] requestContentDigest, byte[] requestSignature, PublicKey publicKey) throws Exception {
        byte[] contentDigest = digestSha256(requestMessage);

        if (!Arrays.equals(requestContentDigest, contentDigest)) {
            return false;
        }
        Signature signature = Signature.getInstance("Sha256withRSA");
        signature.initVerify(publicKey);
        signature.update(contentDigest);
        return signature.verify(requestSignature);
    }

    public static boolean verifySignature512(byte[] requestMessage, byte[] requestContentDigest, byte[] requestSignature, PublicKey publicKey) throws Exception {
        byte[] contentDigest = digestSha512(requestMessage);

        if (!Arrays.equals(requestContentDigest, contentDigest)) {
            return false;
        }
        Signature signature = Signature.getInstance("Sha512withRSA");
        signature.initVerify(publicKey);
        signature.update(contentDigest);
        return signature.verify(requestSignature);
    }

    public static byte[] digestSha256(byte[] requestMessage){
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            return digest.digest(requestMessage);
        } catch (Exception e){
            return null;
        }
    }

    public static byte[] digestSha512(byte[] requestMessage){
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-512");
            return digest.digest(requestMessage);
        } catch (Exception e){
            return null;
        }
    }

    public static PublicKey get(String keyPath)
            throws Exception {
        Reader reader = new FileReader(keyPath);
        PublicKey key;

        try {
            org.bouncycastle.util.io.pem.PemObject spki = new org.bouncycastle.util.io.pem.PemReader(reader).readPemObject();
            key = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(spki.getContent()));
        } catch (Exception ex) {
            FileInputStream fin = new FileInputStream(keyPath);
            CertificateFactory f = CertificateFactory.getInstance("X.509");
            X509Certificate certificate = (X509Certificate)f.generateCertificate(fin);
            key = certificate.getPublicKey();
        }
        return key;
    }
}

Output:

-----------------------------------------------------------------------------------------------------------------------------------------
Message to sign:
abc123
-----------------------------------------------------------------------------------------------------------------------------------------
X-Content-Digest: SHA256 bKE9UspwyIPg8LsQHkJaiehiTeUdstI5JZOvaoQRgJA=
X-Signature: RSA-SHA256 H9DF4NYV9YOZ3B3iogDIdlTzzQpKGWniQNHF5ZxladLes0MDcFopUSzyO6XiO1Y/AVBGLK18iq2nCc8ho+fXb6c4V08/PSE4lrGJu7z8dAs9UwodDgAx3+TXBV8iNkGtj3XThy7QhvruPA0txRLgdaRmKSJsBSoR7HK6LC0ES2LYzypQFXuQ+4LInWETPc4Ttp9bgSf/h07bZaQMlbO29hIQXZc31WCVTGmsJOG+TMBdF+CpWF04sj12ThR539VCpGrJRrE6xsYSg2VQMgo9t2XkcC/nn3Z4FOMD4o5yuwjHHJO1Hs4wyZfpSehIT96pYwvhkyMM5fS0Ms/Po9WUUg==
-----------------------------------------------------------------------------------------------------------------------------------------
X-Content-Digest: SHA512 xwtd2ev7b1HQnUEytxcMnSB1CnhS8AaA9lZY8DEOgQBW5nY8NMmgCw6UAHb1RJXBafwjAszrMSA5JxxDRpUH3A==
X-Signature: RSA-SHA512 UT0UlWI06+pYg+OuJGCaoIua23lq/k3yATkO9wQOl7BGLO56t7dvVZQz8UYtzIUhTrDktw9McqyTncDH8bZKMNMMCPLR7K3xAe3gCgipYE8VSP8uVeLDlqKhc/4OO+HDL6T6L44L1dwy5jKBVbVxDDKib7b0lLtTUtTHIh9WOX74hF6P3OiAZ8CD7tJg4QjngJ0GcM9WKXzfDNxVnOzGkhSarhCu3vsUP7QwG2um54uaADgqcJoJvVVyhlwOPF4kPH8SaAPItUIbz46h4bpF182YFZ7QJeg8TmsqXeOdO2MPdKOPYQsPfwZVs/UFkl7Z0oC5WE9UX7Ds9B7/VkOudw==
-----------------------------------------------------------------------------------------------------------------------------------------
Signature verification SHA256: true
Signature verification SHA512: true
-----------------------------------------------------------------------------------------------------------------------------------------

.Net C# code attempt:

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace VAS
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("-----------------------------------------------------------------------------------------------------------------------------------------");
            byte[] messageAsByte = File.ReadAllBytes(@"C:\Lab\Cert\data.txt");
            Console.WriteLine("Message to sign:");
            Console.WriteLine(Encoding.UTF8.GetString(messageAsByte));
            Console.WriteLine("-----------------------------------------------------------------------------------------------------------------------------------------");

            var publicKey = LoadPublicKey(@"C:\Lab\Cert\public.pem");
            var privateKey = LoadPrivateKey(@"C:\Lab\Cert\private.pem");

            var sha256OfMessage = digestSha256(messageAsByte);
            var sha512OfMessage = digestSha512(messageAsByte);

            string Sha256ContentDigest = Convert.ToBase64String(sha256OfMessage);
            string Sha512ContentDigest = Convert.ToBase64String(sha512OfMessage);

            HashAlgorithm hash256Algorith = SHA256Managed.Create();
            HashAlgorithm hash512Algorith = SHA256Managed.Create();

            byte[] sig256 = privateKey.SignData(messageAsByte, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
            byte[] sig512 = privateKey.SignData(messageAsByte, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);

            var sig64256 = Convert.ToBase64String(sig256);
            var sig64512 = Convert.ToBase64String(sig512);


            Console.WriteLine("X-Content-Digest: SHA256 " + Sha256ContentDigest);
            Console.WriteLine("X-Signature: RSA-SHA256 " + sig64256);
            Console.WriteLine("-----------------------------------------------------------------------------------------------------------------------------------------");
            Console.WriteLine("X-Content-Digest: SHA512 " + Sha512ContentDigest);
            Console.WriteLine("X-Signature: RSA-SHA512 " + sig64512);
            Console.WriteLine("-----------------------------------------------------------------------------------------------------------------------------------------");

            var verify256 = publicKey.VerifyData(messageAsByte, CryptoConfig.MapNameToOID("SHA256"), sig256);
            var verify512 = publicKey.VerifyData(messageAsByte, CryptoConfig.MapNameToOID("SHA512"), sig512);

            Console.WriteLine("Signature verify 256: " + verify256);
            Console.WriteLine("Signature verify 512: " + verify512);
            Console.ReadKey();
        }

        public static RSACryptoServiceProvider LoadPublicKey(String path)
        {
            System.IO.StreamReader fileStream = File.OpenText(path);
            PemReader pemReader = new PemReader(fileStream);
            AsymmetricKeyParameter KeyParameter = (AsymmetricKeyParameter)pemReader.ReadObject();
            RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)KeyParameter);
            RSACryptoServiceProvider csp = new RSACryptoServiceProvider();// cspParams);
            csp.ImportParameters(rsaParams);
            return csp;

        }

        public static RSACryptoServiceProvider LoadPrivateKey(String path)
        {
            System.IO.StreamReader fileStream = File.OpenText(path);
            PemReader pemReader = new PemReader(fileStream);
            AsymmetricCipherKeyPair KeyParameter = (AsymmetricCipherKeyPair)pemReader.ReadObject();
            RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)KeyParameter.Private);
            RSACryptoServiceProvider csp = new RSACryptoServiceProvider();// cspParams);
            csp.ImportParameters(rsaParams);
            return csp;
        }

        public static byte[] digestSha256(byte[] requestMessage)
        {
            SHA256Managed shHash = new SHA256Managed();
            return shHash.ComputeHash(requestMessage);
        }

        public static byte[] digestSha512(byte[] requestMessage)
        {
            SHA512Managed shHash = new SHA512Managed();
            return shHash.ComputeHash(requestMessage);
        }
    }
}

Output:

-----------------------------------------------------------------------------------------------------------------------------------------
Message to sign:
abc123
-----------------------------------------------------------------------------------------------------------------------------------------
X-Content-Digest: SHA256 bKE9UspwyIPg8LsQHkJaiehiTeUdstI5JZOvaoQRgJA=
X-Signature: RSA-SHA256 Wo0dFOfzAJJZTb4zpOHkPVdpgWS1K2Q5IdAAD1wQ+w1veAIbmu+XByBHAbme0PiazdqF6QokFm9IudF7NmyqNjNybIKSuTRPUiP474/kliQl7lDiJJoFejBIaVwQhHdds0CkomZZPulZZSYuIi7cqODaKCXxe/Js9tm/htMu3Wd6nejgaoMX3TGXHWyE6ixJI8Zq7ysD6yjksIWlYthsd0WmCR6mVTKR9zo7BiVPxYsOcJ7MFLSvyJgHHoFmXG9KBZhcA1rx8RquvWLGKxU+WWbt7u/9OqY+HKGPCPo2/S1xmdTP2kiVp1zhQ0JQ4uBgP9nkNqrBxh3QzSZgsCbJKg==
-----------------------------------------------------------------------------------------------------------------------------------------
X-Content-Digest: SHA512 xwtd2ev7b1HQnUEytxcMnSB1CnhS8AaA9lZY8DEOgQBW5nY8NMmgCw6UAHb1RJXBafwjAszrMSA5JxxDRpUH3A==
X-Signature: RSA-SHA512 V47yMVpBunwkUVz0lmi5ZJkYkj2+C9V3YX1MB7OaDvobCGc9F0vBoEsxsV0sDIR2gZsHVMowXFU2bHzIoNdeGz+iyichQ89fJXYP+qPQUZO42t0UXfefX/9LlMbkGlzOqFvfBkcOFidhF9x36ZGPcC6C9AjOC7r1sqL/IBxNENuknhcbBMzHHpJZXFzVo09U/p7LIs3kJxAE9TLkR4ir2syAfisKrbJYCTSZnwm38ikR35mMmigme8eByE6GuOmizshv7lrtd4K5d0RA1jWM1TrNKpLqil4IWbrYQXZCBnHUmLH4fTD7aGIpM+SxQXLBV/lDhWA3O8vXDdFnW0llxQ==
-----------------------------------------------------------------------------------------------------------------------------------------
Signature verify 256: True
Signature verify 512: True

Testkeys and data

private.pem:

-----BEGIN RSA PRIVATE KEY-----
MIIEoQIBAAKCAQBk04fDxgG0eV/b7wcTYK7kq72w4YMzlPyBy6hERHWD2DhuM6TQ
MF7cafxc4b8krGMBqgV9m7AQxhWn4GCmCHljacXivTc1qBp3S54IitZFqvyGhnC0
dqKshqaL6z/S1kbiPZmiiXpZScYkje5pxY7k11PTopqnV9/g89Cu+PDEd7KcA0XE
XbYaEZtufvahZBmbF5mQPAr5YwGDgrR16CiAGi3dcWqX7g7AJb6bSJQp1SEWYVHU
klSdOtIJPgTDB57VIC8klKJ0c2Lnn3M+qPl6aD0qLTyl2QH1q97G+7E0e2dYAAbX
j0uU8753iEE/nHeOz09ACkIdLw9e97Kmka4DAgMBAAECggEAV9DE1oaGxaFRFEVD
bGUw7omGVaCUnUCODJ5Ml+joUUTpIVJpocn/VQoaeutDh7V9Jd3nmlcXKgTcp7KN
ew62axec+rbCd0FKi8yYf+gsZ9Fcz+4YC5WoaYt9UzA6DnACnNn6Dc6feVT/9qaH
mCgxJK9Gm3VsLYQjwdGZWEwJp5NhBXDHMAPIKJqGfI6v3XI3DOa/VPy4zCMrwMpb
Pps0NOMXiwOmWlDVZsDdc36/oICHpib3qHH9Crgbo4i3hDiCCnC97fJiZW6FjfiJ
TtXAIPDAfMIW/etLD6lI9O0s3IbcRf4GjnkmM/JMaJnV9mqqN4Nrn57uDyUC5Ged
2/v6gQKBgQCpWGSe16bFYZQsZunJAcdRGqoj0o3dCb3HpB1pnnKdahIsBYguLlnm
y2QaVXuFPOUMkRfrOGDITP4hSUiN0hsFT1uThE5IsT4u2KdUe2kSlgWerihPWfuZ
UO5w0ag3mgv4avUlg9/wAlRbq7L9s+QivnNxsR6aSuyb+cqLWW8WuQKBgQCYa2bp
FTWO5MDRxia4rHvcj+/4bt7zFwX1JUwfbFR8VtUul/Wk5w2JnzEQgF+Td7gJJxv8
u4JJxZNh8TOqek58lyg1KQKSod8mp8CnW9A2utU2MapZsCxyY7T1jgmXVvcXCQ3W
eJs1VpgQnoZxbzqbV9muQWjQRCCSR/WQ6hBMmwKBgG7G8vNxkJe30E0HeVFTR4ZH
khri5og8khfhxJfN3Z4ZwA9qAv5qtcajMDWFy8qJ3i/NTj9B3xXIP8mYfczAL4rW
scobF3a38zyD31oFbOOKndyCgr391/cgGQpWK9tLex8jIIBM9xWzAGoDNJB/t/H+
cdhii+lUr9kMmzFy7JeJAoGABR3V3o0vtxRGxMP6GMjxf331eEmAgniLYqdV3tgs
HeBsV5wSSu7WrYACjaNBkhm6u9PsRJem0AMp52fJbDee2t/YIbC2vWVhsFKBTRzv
6GZtMdyI82nOlCh0sqmJ+OKaeNN8+24hB7FYeXZY3QX22bAhRpA7jII89awkujCh
S3ECgYBNdGKf5NXxL1n//7GlBsH8sIyNUnHN4dQOORPdSSsynqDcpbdkRFkBIioF
5Q70DOhyS69F8Yu4d1qr09E7AbFpMmQjieDwzdZ6z0b9WInbcKo71FqCaZzz8azt
AMG22E827GX9z7F207rPf7GWpvhpGjzbxHXGXSEyFy2CvetpAA==
-----END RSA PRIVATE KEY-----

public.pem:

-----BEGIN PUBLIC KEY-----
MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQBk04fDxgG0eV/b7wcTYK7k
q72w4YMzlPyBy6hERHWD2DhuM6TQMF7cafxc4b8krGMBqgV9m7AQxhWn4GCmCHlj
acXivTc1qBp3S54IitZFqvyGhnC0dqKshqaL6z/S1kbiPZmiiXpZScYkje5pxY7k
11PTopqnV9/g89Cu+PDEd7KcA0XEXbYaEZtufvahZBmbF5mQPAr5YwGDgrR16CiA
Gi3dcWqX7g7AJb6bSJQp1SEWYVHUklSdOtIJPgTDB57VIC8klKJ0c2Lnn3M+qPl6
aD0qLTyl2QH1q97G+7E0e2dYAAbXj0uU8753iEE/nHeOz09ACkIdLw9e97Kmka4D
AgMBAAE=
-----END PUBLIC KEY-----

data.txt:

abc123

I also tried signing with OpenSSL, and that gives the same result i get with C#. Any help would be appricated so I can handle the data that is generated in Java.

Thanks!

The difference is in handling the hash. In .NET you are handling it correctly:

byte[] sig256 = privateKey.SignData(messageAsByte, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

however in Java, for some reason, you are feeding a precomputed hash value instead of the data:

byte[] contentDigest = digestSha256(requestMessage);
...
signature.update(contentDigest);

In other words, your data is hashed, and then the hash over the data is hashed.

Remember that signature generation in general includes the hashing of the data. Sometimes you can feed a precomputed hash value into the signature generation / verification, but commonly you'll have to call a specifically named method for that, calls such as update are for the message data itself.

Both .NET and Java use PKCS#1 v1.5 padding in your code snippets. PKCS#1 v1.5 padding for signature generation is indeed deterministic and considered secure. PSS is a newer, non-deterministic and more secure method and should be preferred for new protocols & applications.

As a small bonus, here is some code for testing:

private static final String PUB_BASE_64 = "MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQBk04fDxgG0eV/b7wcTYK7k" + 
            "q72w4YMzlPyBy6hERHWD2DhuM6TQMF7cafxc4b8krGMBqgV9m7AQxhWn4GCmCHlj" + 
            "acXivTc1qBp3S54IitZFqvyGhnC0dqKshqaL6z/S1kbiPZmiiXpZScYkje5pxY7k" + 
            "11PTopqnV9/g89Cu+PDEd7KcA0XEXbYaEZtufvahZBmbF5mQPAr5YwGDgrR16CiA" + 
            "Gi3dcWqX7g7AJb6bSJQp1SEWYVHUklSdOtIJPgTDB57VIC8klKJ0c2Lnn3M+qPl6" + 
            "aD0qLTyl2QH1q97G+7E0e2dYAAbXj0uU8753iEE/nHeOz09ACkIdLw9e97Kmka4D" + 
            "AgMBAAE=";
private static final String SIG_SHA256_DOTNET_BASE_64 = "Wo0dFOfzAJJZTb4zpOHkPVdpgWS1K2Q5IdAAD1wQ+w1veAIbmu+XByBHAbme0PiazdqF6QokFm9IudF7NmyqNjNybIKSuTRPUiP474/kliQl7lDiJJoFejBIaVwQhHdds0CkomZZPulZZSYuIi7cqODaKCXxe/Js9tm/htMu3Wd6nejgaoMX3TGXHWyE6ixJI8Zq7ysD6yjksIWlYthsd0WmCR6mVTKR9zo7BiVPxYsOcJ7MFLSvyJgHHoFmXG9KBZhcA1rx8RquvWLGKxU+WWbt7u/9OqY+HKGPCPo2/S1xmdTP2kiVp1zhQ0JQ4uBgP9nkNqrBxh3QzSZgsCbJKg==";
private static final String SIG_SHA256_JAVA_BASE_64 =   "H9DF4NYV9YOZ3B3iogDIdlTzzQpKGWniQNHF5ZxladLes0MDcFopUSzyO6XiO1Y/AVBGLK18iq2nCc8ho+fXb6c4V08/PSE4lrGJu7z8dAs9UwodDgAx3+TXBV8iNkGtj3XThy7QhvruPA0txRLgdaRmKSJsBSoR7HK6LC0ES2LYzypQFXuQ+4LInWETPc4Ttp9bgSf/h07bZaQMlbO29hIQXZc31WCVTGmsJOG+TMBdF+CpWF04sj12ThR539VCpGrJRrE6xsYSg2VQMgo9t2XkcC/nn3Z4FOMD4o5yuwjHHJO1Hs4wyZfpSehIT96pYwvhkyMM5fS0Ms/Po9WUUg==";


public static void main(String[] args) throws Exception {
    KeyFactory rsaKeyFactory = KeyFactory.getInstance("RSA");
    PublicKey pub = rsaKeyFactory.generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(PUB_BASE_64)));
    Cipher rsa = Cipher.getInstance("RSA/ECB/NoPadding");
    rsa.init(Cipher.DECRYPT_MODE, pub);

    {
        byte[] sig = Base64.getDecoder().decode(SIG_SHA256_JAVA_BASE_64);
        byte[] plainSigJava = rsa.doFinal(sig);
        System.out.println(Hex.toHexString(plainSigJava));
    }
    {
        byte[] sig = Base64.getDecoder().decode(SIG_SHA256_DOTNET_BASE_64);
        byte[] plainSigDotNet = rsa.doFinal(sig);
        System.out.println(Hex.toHexString(plainSigDotNet));
    }

    byte[] hashSha256 = Base64.getDecoder().decode("bKE9UspwyIPg8LsQHkJaiehiTeUdstI5JZOvaoQRgJA=");
    System.out.println(Hex.toHexString(hashSha256));
}

prints:

0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420efaaeb3b1d1d85e8587ef0527ca43b9575ce8149ba1ee41583d3d19bd130daf8
0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d0609608648016503040201050004206ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090
6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090

Note that the last signature "decryption" is the .NET one and contains the right hash value, printed on the final line.

Sorry, I used a non-standard Hex decoder, the rest is plain Java that you can put in a class definition.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM