java - 无法将 SHA256 与来自 Java on .Net c# 的 RSA 签名进行匹配

标签 java c# cryptography

我有一些 Java 代码,可以使用 SHA256withRSA 成功验证和签署消息。但是,当我尝试使用 C# 代码验证相同的数据时,我得到了不同的签名,并且签名验证失败。由于 SHA 值匹配,我认为它与代码页无关。我尝试了多种方法来解决这个问题,但尚未失败,所以任何想法都非常受欢迎。

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

输出:

-----------------------------------------------------------------------------------------------------------------------------------------
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# 代码尝试:

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

输出:

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

测试 key 和数据

私有(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-----

数据.txt:

abc123

我还尝试使用 OpenSSL 进行签名,这得到了与使用 C# 得到的相同结果。任何帮助都会被应用,以便我可以处理用 Java 生成的数据。

谢谢!

最佳答案

区别在于处理哈希。在 .NET 中,您可以正确处理它:

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

但是在 Java 中,由于某种原因,您提供的是预先计算的哈希值而不是数据:

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

换句话说,您的数据经过哈希处理,然后对数据进行哈希处理。

请记住,签名生成通常包括数据的散列。有时,您可以将预先计算的哈希值提供给签名生成/验证,但通常您必须为此调用专门命名的方法,诸如 update 之类的调用是针对消息数据本身的。 p>

.NET 和 Java 在代码片段中都使用 PKCS#1 v1.5 填充。用于签名生成的 PKCS#1 v1.5 填充确实是确定性的并且被认为是安全的。 PSS 是一种更新的、非确定性的、更安全的方法,应该是新协议(protocol)和应用程序的首选方法。

作为一个小奖励,这里有一些用于测试的代码:

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

打印:

0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420efaaeb3b1d1d85e8587ef0527ca43b9575ce8149ba1ee41583d3d19bd130daf8
0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d0609608648016503040201050004206ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090
6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090

请注意,最后一个签名“解密”是 .NET 签名,并且包含正确的哈希值,打印在最后一行。

抱歉,我使用了非标准的十六进制解码器,其余的都是纯 Java,您可以将其放入类定义中。

关于java - 无法将 SHA256 与来自 Java on .Net c# 的 RSA 签名进行匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59722926/

相关文章:

javascript - 始终解密为纯文本的加密功能,即使使用不正确的 key 也是如此

可以在具有 32Kb 内存的 8 位设备上实现 RSA 加密吗?

java - 特定HQL查询( hibernate )的连接错误预期路径

java - 在 OptaPlanner session 安排示例中,是否可以根据房间的最小容量将 session 分配到房间?

c# - 运行 C# .NET Winform 应用程序,该应用程序使用 SQL Server 作为数据库,仅将 .mdf 文件放置在用户 PC 上

c# - 从字符串中解析一个值

java - 为什么泛型类型只能为静态方法定义?

java - Arraylist.clear 清除所有数组列表?

c# - linq to实体更改代码中的数据库连接字符串

c++ - 在 Crypto++ 中使用 Curve25519 签名