Signature.verify () returns false in java

First of all, I see that there are other posts with this question, but I don't have the same problem as mine, i.e. signature.verify()

returns unexpectedly false

.

Here's my code:

private static String encriptar(String xmlSolicitud, PrivateKey privateKey)
        throws Exception {

    Signature signature=Signature.getInstance("SHA1withRSA");
    signature.initSign(privateKey);
    signature.update(xmlSolicitud.getBytes(Charset.forName("UTF-8")));
    byte[] signatureValue = signature.sign();
    String response = Base64.encode(signatureValue);
    signature.initVerify(keyReader.publicKeyRead(Reference.rutaPublicKeyTest));
    System.out.println(signature.verify(signatureValue));
    return response;
}

      

And this is how I read in the keys (if needed):

public static PrivateKey privateKeyRead(String filename)
        throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {

    File f = new File(filename);
    FileInputStream fis = new FileInputStream(f);
    DataInputStream dis = new DataInputStream(fis);
    byte[] keyBytes = new byte[(int)f.length()];
    dis.readFully(keyBytes);
    dis.close();

    PKCS8EncodedKeySpec spec =
                new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    return kf.generatePrivate(spec);
}

public static PublicKey publicKeyRead(String filename)
        throws Exception {

    File f = new File(filename);
    FileInputStream fis = new FileInputStream(f);
    DataInputStream dis = new DataInputStream(fis);
    byte[] keyBytes = new byte[(int)f.length()];
    dis.readFully(keyBytes);
    dis.close();

    X509EncodedKeySpec spec =
                new X509EncodedKeySpec(keyBytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    return kf.generatePublic(spec);
}

      

+3


source to share


1 answer


Signature state reset after invocation sign

. According to the documentation :

Calling this method resets this signature object to the state it was in when it was previously initialized for signing by calling initSign(PrivateKey)

. That is, the object is reset and available to generate another signature from the same signer, if necessary, by means of a new call update

and sign

.

You need to update the signature again with the bytes that were signed:



private static String encriptar(String xmlSolicitud, PrivateKey privateKey)
        throws Exception {

    Signature signature=Signature.getInstance("SHA1withRSA");
    signature.initSign(privateKey);
    signature.update(xmlSolicitud.getBytes(Charset.forName("UTF-8")));

    byte[] signatureValue = signature.sign();
    String response = Base64.encode(signatureValue);

    signature.initVerify(keyReader.publicKeyRead(Reference.rutaPublicKeyTest));
    signature.update(xmlSolicitud.getBytes(Charset.forName("UTF-8"))); // <-- Here

    System.out.println(signature.verify(signatureValue)); // <-- Will print true

    return response;
}

      


On the other hand, it looks like you are signing XML content. It is probably wise to use XML signatures to avoid canonicalization issues.

+2


source







All Articles