Я пытаюсь сделать подпись SHA256 с помощью ECDSA, используя JCE и LunaProvider, совместимую с провайдером BouncyCastle.
Я использую следующий код для подписи сообщения с использованием LunaProvider:
Signature signature = Signature.getInstance("SHA256withECDSA", "LunaProvider");
signature.initSign(keyPair.getPrivate());
byte[] messageHash = sha256Hash(message);
signature.update(messageHash);
byte[] signatureValue = signature.sign();
int rLength = signatureValue[3];
int rStartIndex = 4;
byte[] sigR = Arrays.copyOfRange(signatureValue, rStartIndex, rStartIndex + rLength);
int sLength = signatureValue[rStartIndex + rLength + 1];
int sStartIndex = rStartIndex + rLength + 2;
byte[] sigS = Arrays.copyOfRange(signatureValue, sStartIndex, sStartIndex + sLength);
и проверяю его следующим образом :
Signature signature = Signature.getInstance("SHA256withECDSA", "LunaProvider");
signature.initVerify(publicKey);
signature.update(messageHash);
boolean isValid = signature.verify(signatureValue);
Все работает как положено.
Затем я пытаюсь проверить подпись с помощью BouncyCastle:
private static boolean verify(byte[] messageHash, byte[] publicKey, byte[] sigR, byte[] sigS) {
ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1");
ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest()));
ECPublicKeyParameters pubKey = new
ECPublicKeyParameters(spec.getCurve().decodePoint(publicKey), Sign.CURVE);
signer.init(false, pubKey);
return signer.verifySignature(messageHash, new BigInteger(1, sigR), new BigInteger(1, sigS));
}
private static class Sign {
private static final X9ECParameters CURVE_PARAMS = CustomNamedCurves.getByName("secp256r1");
private static final ECDomainParameters CURVE = new ECDomainParameters(
CURVE_PARAMS.getCurve(), CURVE_PARAMS.getG(), CURVE_PARAMS.getN(), CURVE_PARAMS.getH());
}
, но проверка не удалась. Что я делаю не так?