RSA SignatureException: Signature length not corre

2019-08-15 06:12发布

I am having issues signing an rsa signature. I have a signature that has been encrypted with a private key. I have an issue when trying to validate it with the public key however. I get the following exception:

java.security.SignatureException: Signature length not correct: got 336 but was expecting 128
    at sun.security.rsa.RSASignature.engineVerify(RSASignature.java:189)
    at java.security.Signature$Delegate.engineVerify(Signature.java:1219)
    at java.security.Signature.verify(Signature.java:652)
    at XmlReader.main(XmlReader.java:65)

I have retrieved my signature and public key the following way:

    BigInteger modulus = new BigInteger(Base64.getDecoder().decode(publicKeyString));
    BigInteger exponent = new BigInteger(Base64.getDecoder().decode("AQAB"));

    RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PublicKey pubKey = keyFactory.generatePublic(keySpec);

    byte[] sigToVerify = Base64.getDecoder().decode(signatureString);
    Signature sig = Signature.getInstance("MD5WithRSA");
    sig.initVerify(pubKey);
    boolean verifies = sig.verify(sigToVerify);

The application fails at the last line. Any thoughts as to where this exception is caused?

UPDATE:

Added data for signature to be verified:

        String data = "...." //hidden since sensitive data
        byte[] dataBytes = Base64.getEncoder().encode(data.getBytes());
        dataBytes = Base64.getDecoder().decode(dataBytes);

2条回答
贪生不怕死
2楼-- · 2019-08-15 06:35

Before calling sig.verify(sigToVerify) you should call

sig.update(data);

passing the data you're verifying signature for.

And make sure that calling verify in your argument you have signature bytes only.

查看更多
放我归山
3楼-- · 2019-08-15 06:52

Well, the signature size is obviously not correct. This means that at least the signature is not formatted correctly; an RSA signature by itself is always the size of the modulus in bytes (identical to the key size, in your case a short 1024 bit key).

algrid is right that usually you'd have to update the signature first. So it would be logical that the input of the signature is prefixed with the data that was signed. In that case the last 128 bytes are probably the signature, and the bytes before that are the data.

It is also possible that the signature is not a "raw" signature but a formatted signature, e.g. using the PKCS#7 / CMS syntax or PGP syntax. In that case you would need an library to decode it.

Note that you cannot verify a signature without the data that was signed, or at least the hash over the data. You can only check the correctness of the signature in that case (by validating the padding performed before modular exponentiation for RSA, in case we need to go into details).

查看更多
登录 后发表回答