Anton Podolskiy
Anton Podolskiy

Reputation: 35

Java Validate signature C# equivalent

I'm trying to find an equivalent of this Java code:

public String signData(String data, String privateKey) {
    try {
        byte[] bytes = data.getBytes("UTF8");
        PKCS8EncodedKeySpec prKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
        PrivateKey prKey = KeyFactory.getInstance("RSA").generatePrivate(prKeySpec);

        Signature sig = Signature.getInstance("SHA512withRSA");
        sig.initSign(prKey);
        sig.update(bytes);
        byte[] signatureBytes = sig.sign();
        return new String(Base64.encodeBase64(signatureBytes));
    } catch (Exception ex) {
    }
    return null;
}

And

public boolean validateSignature(String data, String publicKey, String signature) {
    try {
        byte[] bytes = data.getBytes("UTF8");
        X509EncodedKeySpec pbKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
        PublicKey pbKey = KeyFactory.getInstance("RSA").generatePublic(pbKeySpec);

        Signature sig = Signature.getInstance("SHA512withRSA");
        sig.initVerify(pbKey);
        sig.update(bytes);

        return sig.verify(Base64.decodeBase64(signature));
    } catch (Exception ex) {
    }

    return false;
}

This code doesn't seem to work. Probably I missed something. I found several similar posts, but haven't found an answer.

    public String signData(String data, String privateKey)
    {
        byte[] bytes = Encoding.UTF8.GetBytes(data);
        var rsa = RSA.Create();
        rsa.ImportPkcs8PrivateKey(Convert.FromBase64String(privateKey), out _);
        byte[] signedData = rsa.SignData(bytes, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);

        return Convert.ToBase64String(signedData);
    }

    public bool validateSignature(String data, String publicKey, String signature)
    {
        var bytes = Convert.FromBase64String(publicKey);
        var rsa = RSA.Create();
        rsa.ImportSubjectPublicKeyInfo(bytes, out _);
        var rsaParams = rsa.ExportParameters(false);

        return rsa.VerifyHash(Encoding.UTF8.GetBytes(data), Convert.FromBase64String(signature), HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
    }

It's blown my mind) I hope someone has an answer) Thanks

Upvotes: 0

Views: 531

Answers (1)

Oguz Ozgul
Oguz Ozgul

Reputation: 7187

The problem is in the validateSignature method where you call VerifyHash() for verifying the signature. The name of the first parameter is rgbHash and the documentation for it says:

Parameters rgbHash Byte[] The hash value of the signed data.

This method is for verifying a signature for an already calculated hash, but you are trying to verify a signature by providing the data itself, so changing VerifyHash() call to VerifyData() should do the trick:

public static bool validateSignature(String data, String publicKey, String signature)
{
    var bytes = Convert.FromBase64String(publicKey);
    var rsa = RSA.Create();
    rsa.ImportSubjectPublicKeyInfo(bytes, out _);

    // Not used in the provided code.
    // var rsaParams = rsa.ExportParameters(false);

    return rsa.VerifyData(Encoding.UTF8.GetBytes(data), Convert.FromBase64String(signature), HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
}

Upvotes: 1

Related Questions