Olá pessoal,
Estou precisando fazer um software que valide assinatura digital, gerado a partir de um hardware, esse hardware cria o par de chaves, e fornece a chave pública e assinatura para validação, que estão no fonte abaixo, no hardware consegui validar a assinatura, entrei em contato com o fabricante ele me passou um programa em C utilizando o OPEN SSL com linux, conseguimos validar a assinatura através dele.Tentei utilizar bibliotecas nativas do Java mas não funcionaram, como o fabricante passou em OPEN SSL, procurei por biblioteca que implementasse achei bouncycastle,mas sem sucesso na validação.
Fonte:
public static void main(String[] args) {
// == Gerado através do hardware
// pubkey 44E029518380A9D79A34DCFA8A9044CAD6BA177BA279DD1225283E23473D014B95F6F3CC29CAF7B2C22BF4C30487E9302FEFB84949828556FC3037E47EDE6783
// signature 9F5C40B1A531C0C97ABA0156DB9CC9D915E6F6D20F88F83F782E85C7FEFA0940230EF1C814EC1183FB747886909980659D0B54F027B7D107F6C72DF148C701E3
// ================
// message C0535E4BE2B79FFD93291305436BF889314E4A3FAEC05ECFFCBB7DF31AD9E51A
byte[] pubKey = DatatypeConverter.parseHexBinary("0444E029518380A9D79A34DCFA8A9044CAD6BA177BA279DD1225283E23473D014B95F6F3CC29CAF7B2C22BF4C30487E9302FEFB84949828556FC3037E47EDE6783");
byte[] message = DatatypeConverter.parseHexBinary("C0535E4BE2B79FFD93291305436BF889314E4A3FAEC05ECFFCBB7DF31AD9E51A");
byte[] signature = DatatypeConverter.parseHexBinary("9F5C40B1A531C0C97ABA0156DB9CC9D915E6F6D20F88F83F782E85C7FEFA0940230EF1C814EC1183FB747886909980659D0B54F027B7D107F6C72DF148C701E3");
try {
isValidSignature(pubKey, message, signature);
} catch (Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("unused")
private static boolean isValidSignature(byte[] pubKey, byte[] message, byte[] signature) throws Exception {
Signature ecdsaVerify = Signature.getInstance("SHA256withECDSA", new BouncyCastleProvider());
ecdsaVerify.initVerify(uPublicKey(pubKey));
ecdsaVerify.update(message);
return ecdsaVerify.verify(signature); //>>AQUI OCORRE EXCEÇÃO
}
public static PublicKey uPublicKey(byte[] pubKey) throws Exception {
KeyFactory kf = null;
ECNamedCurveParameterSpec ecNamedCurveParameterSpec = ECNamedCurveTable.getParameterSpec("secp256r1");
ECCurve curve = ecNamedCurveParameterSpec.getCurve();
EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, ecNamedCurveParameterSpec.getSeed());
java.security.spec.ECPoint ecPoint = ECPointUtil.decodePoint(ellipticCurve, pubKey);
ECParameterSpec ecParameterSpec = EC5Util.convertSpec(ellipticCurve, ecNamedCurveParameterSpec);
java.security.spec.ECPublicKeySpec publicKeySpec = new java.security.spec.ECPublicKeySpec(ecPoint, ecParameterSpec);
kf = java.security.KeyFactory.getInstance("EC");
PublicKey pk =kf.generatePublic(publicKeySpec);
System.out.println(pk);
return pk;
}
Erro gerado:
Sun EC public key, 256 bits
public x coord: 31153332615377210231832564955526912255697719887445193366304044238956891275595
public y coord: 67830941445434864592771338557307709284905759437898851667074925191488648144771
parameters: org.bouncycastle.jce.spec.ECNamedCurveSpec@304b0cbc
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)
Fontes pesquisa:
How can I get a PublicKey object from EC public key bytes?
ECDSA Example returns "invalid ECDSA signature" for valid signatures