Erro ao verificar a assinatura ECDSA em Java com BouncyCastle

Eu testei uma solução para verificar uma assinatura ECDSA (Como posso obter um objeto PublicKey a partir de bytes de chave pública EC?) que funciona perfeitamente com os dados fornecidos.

Estes são os dados:

byte[] pubKey = DatatypeConverter.parseHexBinary("049a55ad1e210cd113457ccd3465b930c9e7ade5e760ef64b63142dad43a308ed08e2d85632e8ff0322d3c7fda14409eafdc4c5b8ee0882fe885c92e3789c36a7a");
byte[] message = DatatypeConverter.parseHexBinary("54686973206973206a75737420736f6d6520706f696e746c6573732064756d6d7920737472696e672e205468616e6b7320616e7977617920666f722074616b696e67207468652074696d6520746f206465636f6465206974203b2d29");
byte[] signature = DatatypeConverter.parseHexBinary("304402205fef461a4714a18a5ca6dce6d5ab8604f09f3899313a28ab430eb9860f8be9d602203c8d36446be85383af3f2e8630f40c4172543322b5e8973e03fff2309755e654");

E este é o código (que imprimeverdadeiro):

private static boolean isValidSignature(byte[] pubKey, byte[] message,byte[] signature) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException, InvalidKeySpecException {
    Signature ecdsaVerify = Signature.getInstance("SHA256withECDSA", new BouncyCastleProvider());
    ecdsaVerify.initVerify(getPublicKeyFromBytes(pubKey));
    ecdsaVerify.update(message);
    return ecdsaVerify.verify(signature);
}

private static PublicKey getPublicKeyFromBytes(byte[] pubKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
    ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1");
    KeyFactory kf = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());
    ECNamedCurveSpec params = new ECNamedCurveSpec("prime256v1", spec.getCurve(), spec.getG(), spec.getN());
    ECPoint point =  ECPointUtil.decodePoint(params.getCurve(), pubKey);
    ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, params);
    ECPublicKey pk = (ECPublicKey) kf.generatePublic(pubKeySpec);
    return pk;
}

public static void main (String[] args) {
    System.out.println(isValidSignature(pubKey, message, signature));
}

Meu problema surge quando altero a assinatura e os dados para uma entrada de exemplo de um sistema já implementado:

final static byte[] pubKey = DatatypeConverter.parseHexBinary("0447303876C6FED5550DF3EE1136989FCD87293D54A5D8E2F2F6D7FBE9A81089B889A5917443AF33E696178CEF4C9D6A4288B2745B29AF6C8BCAD1348F78EB9F9B");
final static byte[] message = DatatypeConverter.parseHexBinary("02158001f53611a06e2d1a270000013ed9305dc2780524015110500000002d0100140092569202017aa00c5dd30000000000000000000000000000000007d1000001020001b20788b80059f48d95cdefc8c6000200200030d41e0000012016840310a50733a9870fffd0430100");
final static byte[] signature = DatatypeConverter.parseHexBinary("531F8918FF250132959B01F7F56FDFD9E6CA3EC2144E12A6DA37C281489A3D96");

Novos dados geram este erro:

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:1178)
    at java.security.Signature.verify(Signature.java:612)
    at its.sec.exec.TestProgram.isValidSignature(TestProgram.java:168)
    at its.sec.exec.TestProgram.execution(TestProgram.java:101)
    at its.sec.exec.TestProgram.main(TestProgram.java:55)

Presumo que o problema seja sobre a assinatura que acompanha omensagem segura Porque:

O par de chaves tem o mesmo comprimento e formato que o exemplo. E estão corretos, pois vem do certificado que assina a mensagem.A mensagem em si (carga útil) não deve afetar o processo de segurança.

A última coisa que vale a pena mencionar é que minha documentação diz que a assinatura deve ser precedida por um campo chamado "R" que"contém a coordenada x do ponto da curva elíptica resultante da multiplicação do elemento gerador pela chave privada efêmera" e seu comprimento deve ser o mesmo da assinatura (32 bytes).

Alguém pode me indicar o que estou perdendo aqui?

EDIT: Solução

Como Peter Dettman apontou em sua resposta, osignature não foi formatado corretamente (também o conteúdo também estava incorreto) para ser calculado peloverify() método.Aqui é uma boa explicação que diz principalmente que:

Quando codificado no DER, essa (assinatura) se torna a seguinte sequência de bytes:

0x30 b1 0x02 b2 (vr) 0x02 b3 (vs)

Onde:

b1 é um valor de byte único, igual ao comprimento, em bytes, da lista de bytes restante (do primeiro 0x02 ao final da codificação);b2 é um valor de byte único, igual ao comprimento, em bytes, de (vr);b3 é um valor de byte único, igual ao comprimento, em bytes, de (vs);(vr) é a codificação big endian assinada do valor "r", de tamanho mínimo;(vs) é a codificação big endian assinada do valor "s", de tamanho mínimo.

Aplicando essa mudança,signature cresce para 70 bytes e a execução não gera erros.

questionAnswers(2)

yourAnswerToTheQuestion