0

I have signature created in Java by following code

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
signature = (Signature) rsaSha256.getCipher();

signature.initSign(privateKey);
signature.update(binaryData);
signatureBytes = signature.sign();

By verifying signature in C#, im always getting false. Following code use BouncyCastle library

ISigner signer = SignerUtilities.GetSigner("SHA256withRSA");

using (TextReader sr = new StringReader(publicKey))
    {
       PemReader pr = new PemReader(sr);
       RsaKeyParameters keys = (RsaKeyParameters)pr.ReadObject();

       signer.Init(false, keys);
       signer.BlockUpdate(value, 0, value.Length);
       bool isValid = signer.VerifySignature(signature);

       return isValid;
    }

Following code return false too

private static bool VerifyWithPublicKey(byte[] data, byte[] sig, string publicKey)
    {
        RSACryptoServiceProvider rsa;

        using (var keyreader = new StringReader(publicKey))
        {
            var pemReader = new PemReader(keyreader);
            var y = (RsaKeyParameters)pemReader.ReadObject();
            RSAParameters p1 = DotNetUtilities.ToRSAParameters(y);
            rsa = new RSACryptoServiceProvider();

            rsa.ImportParameters(p1);
        }


        byte[] hash;
        using (var sha256 = SHA256.Create())
        {
            hash = sha256.ComputeHash(data);
        }

        RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(rsa);
        RSADeformatter.SetHashAlgorithm("SHA256");
        //Verify the hash and display the results to the console. 
        if (RSADeformatter.VerifySignature(hash, sig))
        {
            Console.WriteLine("The signature was verified.");
        }
        else
        {
            Console.WriteLine("The signature was NOT verified.");
        }

        // This always returns false
        return rsa.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA256"), sig);
    }

Im out of ideas. Anyone done something similar? If so, can you share your code please

Herm Heyfe
  • 51
  • 1
  • 3
  • Per [this answer](https://stackoverflow.com/questions/37572306/verifying-ecdsa-signature-with-bouncy-castle-in-c-sharp) it looks like the C# verifier is expecting a DER-encoded signature. I can't seem to find documentation on whether there's a standard output format for JCE's `javax.crypto.Signature#sign` method. You could always drop the output you get from Java [here](https://lapo.it/asn1js/) to see if it decodes properly as a DER-encoded ASN.1 signature structure. – lockcmpxchg8b Sep 01 '18 at 18:09
  • @lockcmpxchg8b The X.509/DER vs IEEE-P1363 encoding only applies to DSA and ECDSA, not RSA. (And in DSA and ECDSA .NET wants the IEEE-P1363 version, not the DER version :)) – bartonjs Sep 06 '18 at 16:24

1 Answers1

0

This works for me, I see a difference where you use .GetSigner("SHA256withRSA") but I use "SHA-256withRSA"

    public static bool VerifySignature(byte[] hashBytes, byte[] signatureBytes)
    {
        PemReader pemReader = new PemReader(new StreamReader("PublicKey.pem"));
        RsaKeyParameters parameters = (RsaKeyParameters)pemReader.ReadObject();

        RsaDigestSigner signer = (RsaDigestSigner)SignerUtilities.GetSigner("SHA-256withRSA");
        signer.Init(false, parameters);

        signer.BlockUpdate(hashBytes, 0, hashBytes.Length);
        bool isValid = signer.VerifySignature(signatureBytes);

        return isValid;
    }
Treebeard
  • 64
  • 1
  • 7