Yvon Fanfe
Yvon Fanfe

Reputation: 123

Error decoding signature bytes : "java.security.SignatureException: error decoding signature bytes"

I got this error when trying to verify ECDSA Signature in my class. The error code is:

java.security.SignatureException: error decoding signature bytes.
at org.bouncycastle.jcajce.provider.asymmetric.util.DSABase.engineVerify(Unknown Source)
at java.security.Signature$Delegate.engineVerify(Signature.java:1172)
at java.security.Signature.verify(Signature.java:623)
at SDSGeneration.Signing.verify_signature(Signing.java:88)
at com.sdsweb.modele.VerificationBox.checkSignature(VerificationBox.java:121)
at com.sdsweb.modele.VerificationBox.verifieur(VerificationBox.java:84)
at com.sdsweb.servlet.Authentification.doGet(Authentification.java:55)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)......

I'm calling the method as this in the VerificationBox.java Class :

public Map<Integer, String> checkSignature(String data_digest, Signature SignObject, PublicKey publicKey, byte[] Signaturebyte) throws InvalidKeyException, SignatureException, NoSuchProviderException, NoSuchAlgorithmException{

    Map<Integer, String> erreur_signature = new HashMap<Integer, String>();

    Signing SignVerifier = new Signing();

    SignVerifier.setEcdsa_signature();

    SignVerifier.verify_signature(publicKey, SignVerifier.getEcdsa_signature(), data_digest, Signaturebyte);

    if (SignVerifier.getVerify_result()){
        erreur_signature.put(j, "SIGNATURE ÉRONNÉ, CODE SDS INVALIDE");
        j++;
    }
    return null;

}

This is the SDSGeneration.Signing Class:

package SDSGeneration;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.Signature;
import java.security.KeyPair;
import java.security.SignatureException;

//This class provide an instance of all object which are needed to sign data
public class Signing {

    public Signing() {

    }

    public Signing(KeyPair keygen) {

    }

    //ECDSA Signature Object
    private Signature ecdsa_signature;
    //KeyPair object
    private KeyPair keygen;
    //Final data signature
    private byte[] signature;
    //Boolean variable telling if the signing proccess was succesfful or not
    private Boolean verify_result;

    public Boolean getVerify_result() {
        return verify_result;
    }

    public byte[] getSignature() {
        return signature;
    }


    public KeyPair getKeygen() {
        return keygen;
    }

    public Signature getEcdsa_signature() {
        return ecdsa_signature;
    }

    public void setEcdsa_signature() throws NoSuchAlgorithmException, NoSuchProviderException {

        this.ecdsa_signature = java.security.Signature.getInstance("ECDSA", "BC");
    }

    public void setKeygen(KeyPair keygen) {
        this.keygen = keygen;
    }



    //This method is use to sign data. A call to a  sign  method resets the signature object to the state it was in when previously initialized for signing via a call to  initSign. 
    //That is, the object is reset and available to generate another signature with the same private key, if desired, via new calls to  update  and  sign .
    public void generate_signature(KeyPair keygen, Signature ecdsa_signature, String data) throws InvalidKeyException, SignatureException{

        //inserting private key in signature object
        ecdsa_signature.initSign(keygen.getPrivate());

        //inserting data to sign
        ecdsa_signature.update(data.getBytes());

        //signing
        this.signature = ecdsa_signature.sign();
    }

    //This method is use to sign data. A call to the  verify  method resets the signature object to its state when it was initialized for verification via a call to initVerify . 
    //That is, the object is reset and available to verify another signature from the identity whose public key was specified in the call to  initVerify .
    public void verify_signature(PublicKey keygen, Signature ecdsa_signature, String data, byte[] signature) throws InvalidKeyException, SignatureException{

        //generating the signature
        ecdsa_signature.initVerify(keygen);

        //inserting data to verify
        ecdsa_signature.update(data.getBytes());

        //verifying
        this.verify_result = ecdsa_signature.verify(signature);
    }
}

I wrote a Test class for testing the SDSGeneration.Signing code and everything working well, signing and verifying data, but when importing and using it in my project, the error below occure. This is the Test Class code:

    package SDSGeneration;

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;

public class TestSigning {

    public TestSigning() {
        // TODO Auto-generated constructor stub
    }

    public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, InvalidKeyException, SignatureException {
        // TODO Auto-generated method stub
        GenerateKeyPair new_keypair = new GenerateKeyPair();

        Signing testSign = new Signing();
        testSign.setKeygen(new_keypair.getKeygen());

        testSign.setEcdsa_signature();

        testSign.generate_signature(testSign.getKeygen(), testSign.getEcdsa_signature(), "Fanfe Yvon");

        testSign.verify_signature(testSign.getKeygen().getPublic(), testSign.getEcdsa_signature(), "Fanfe Yvon", testSign.getSignature());

        System.out.println("Signature result : " + testSign.getVerify_result() + " ; signature of data : " + testSign.getSignature());
    }

}

Upvotes: 1

Views: 6276

Answers (1)

Yvon Fanfe
Yvon Fanfe

Reputation: 123

The Problem was that i was using the wrong CHARSET to Encode the signature into the Storage.

I had to encode into convert it to Base64 and encode it in UTF-8 before storing it, like this:

String signTostring = DatatypeConverter.printBase64Binary(signature);
signTostring = URLEncoder.encode(signTostring, "UTF-8");

Whan i want to use it, i do the revrse actions to get the original signature

String st = URLDecoder.decode(code.getSignature(), "UTF-8");
byte[] sign_byte = DatatypeConverter.parseBase64Binary(st); 

Upvotes: 1

Related Questions