Sto sviluppando un'applicazione che deve convalidare le firme SHA256withECDSA
con l'aiuto delle chiavi pubbliche secp256r1
(NIST P-256, P-256, prime256v1).Come posso ottenere un oggetto PublicKey dai byte della chiave pubblica CE?
Le chiavi pubbliche vengono generate da un'applicazione diversa in un momento precedente e memorizzate nel mio database in codifica esadecimale. Il formato della stringa esadecimale qui è equivalente alla stringa esadecimale che OpenSSL genererebbe quando chiama openssl ec -in x.pem -noout -text
su un file x.pem
che è stato precedentemente generato da openssl ecparam -genkey -name secp256r1 -out x.pem
. Il messaggio e la firma sono ricevuti da un'altra applicazione. Si consideri il seguente dati di test:
// Stored in Database
byte[] pubKey = DatatypeConverter.parseHexBinary("049a55ad1e210cd113457ccd3465b930c9e7ade5e760ef64b63142dad43a308ed08e2d85632e8ff0322d3c7fda14409eafdc4c5b8ee0882fe885c92e3789c36a7a");
// Received from Other Application
byte[] message = DatatypeConverter.parseHexBinary("54686973206973206a75737420736f6d6520706f696e746c6573732064756d6d7920737472696e672e205468616e6b7320616e7977617920666f722074616b696e67207468652074696d6520746f206465636f6465206974203b2d29");
byte[] signature = DatatypeConverter.parseHexBinary("304402205fef461a4714a18a5ca6dce6d5ab8604f09f3899313a28ab430eb9860f8be9d602203c8d36446be85383af3f2e8630f40c4172543322b5e8973e03fff2309755e654");
Ora questo dovrebbe essere una firma valida.
Il mio obiettivo è convalidare la firma sul messaggio utilizzando l'API di crittografia Java e/o Bouncycastle. Ho creato un metodo isValidSignature
per questo:
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(getPublicKeyFromHex(pubKey));
ecdsaVerify.update(message);
return ecdsaVerify.verify(signature);
}
ho cercato di estrarre la chiave pubblica:
KeyFactory.generatePublic:
private static PublicKey getPublicKeyFromHex(byte[] pubKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException {
KeyFactory fact = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());
return fact.generatePublic(new X509EncodedKeySpec(pubKey));
}
Ma questo getta una lunghezza java.security.spec.InvalidKeySpecException
(DER più di 4 byte: 26). Cosa posso fare per analizzare questo?
Giusto per consentire la correttezza durante la copia del codice; L'opzione '-noout' per OpenSSL è errata. – CarlosRos
Grazie, corretto. –