0

I have a signature string, Base64 encoded, a message string in json and a public key string - assume it is base64 encoded generated in Java and I need to validate it in C#.

I also have a Java Code which should do the verification correctly, but I just can't get make it run in C#. Any help how to do this please?

import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.codec.binary.Base64;

public class WebHookSecurityUtil
{
    private static final String KEYPAIR_ALGORITHM = "RSA";  // No I18N
    private static final String SIGNATURE_ALGORITHM = "SHA256withRSA";  // No I18N
    private static final String CHARSETNAME = "UTF-8";  // No I18N

    public static boolean verifySignature(String text, String public_key_str, String signature_str) throws Exception
    {
        PublicKey public_key = getPublicKey(public_key_str);

        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(public_key);
        signature.update(text.getBytes(CHARSETNAME));

        byte[] signatureBytes = Base64.decodeBase64(signature_str);

        return signature.verify(signatureBytes);
    }

    public static PublicKey getPublicKey(String public_key) throws Exception
    {
        byte[] bytes = Base64.decodeBase64(public_key);

        X509EncodedKeySpec ks = new X509EncodedKeySpec(bytes);
        KeyFactory kf = KeyFactory.getInstance(KEYPAIR_ALGORITHM);
        return kf.generatePublic(ks);
    }
}

what I tried is and it always returns false.

            RSAParameters pubKey = new RSAParameters();
            // Not sure here...
            pubKey.Modulus =Convert.FromBase64String(publicKey);
            pubKey.Exponent = new byte[] { 1, 0, 1 };

            byte[] buffer = System.Text.UTF8Encoding.UTF8.GetBytes(msg);
            byte[] sig = Convert.FromBase64String(signature);
            RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
            provider.ImportParameters(pubKey);
            bool isValid = provider.VerifyData(buffer, CryptoConfig.MapNameToOID("SHA256"), sig);
            Console.WriteLine("SHA256: " + isValid);
piet.t
  • 11,718
  • 21
  • 43
  • 52
Raupes
  • 1
  • 2
  • Can you please show your C# code and explain exactly what is not working - i.e. Are you getting an exception?, etc. Basically, can you please provide a [mcve] of the C# code, including your test/sample data. – pstrjds Aug 22 '19 at 12:27
  • Please include some sample data - data that you are getting from Java and that you are not able to process in C#. – pstrjds Aug 22 '19 at 14:10

1 Answers1

0

After base 64 encoding you need to perform the code from here starting with DecodeX509PublicKey. Mickeysoft doesn't support "SubjectPublicKeyInfo" structures which are used within X.509 certificates and PUBLIC KEY PEM structures because it doesn't support standards, preferring their own formats. It's starting to change though, but very slowly.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263