Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why ECDSA verification fails in Android using Spongy Castle?

I am trying to verify a signature in Android using spongy castle. This dependency has been added to gradle as:

implementation group: 'com.madgag.spongycastle', name: 'bcpkix-jdk15on', version: '1.58.0.0'

When running below code in Android Flamingo I always get false for verified with different public keys, and signatures. But all of them are valid and verified according to this site. Here is my Android code (I need to use secp256k1 and hex values for key, message, and signature):

String publicKeyHex = "04954ed5969f7d4cc2baa1f0345f037a4758e84058d202feb64885c32dfc62123af4c8ccfba16088fc9cc2bd84594d810ad470706cfddfc17999d291b038f4c9f1";
String messageHex   = "12ca8b3b17607820279c7e0095d655d9ce289e90cccc0e99ae00f5e29f8d6615";
String signatureHex = "3045022100affcf495d11d02fcde6f9cd502975b78dd18b4b50127edef56683ca8534575cf02206f3d92bb26d515d122754c88e92c1d7d8bfc2b35876608b9c75ee9cbcd6fdde9";

byte[] publicKeyBytes = hexStringToByteArray(publicKeyHex);
byte[] messageBytes   = hexStringToByteArray(messageHex);
byte[] signatureBytes = hexStringToByteArray(signatureHex);

final ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1");
final ECNamedCurveSpec params = new ECNamedCurveSpec("secp256k1", spec.getCurve(), spec.getG(),spec.getN());

KeyFactory keyFactory = KeyFactory.getInstance("EC");
ECPoint ecPoint = ECPointUtil.decodePoint(params.getCurve(), publicKeyBytes);
ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(ecPoint, params);
ECPublicKey publicKey = (ECPublicKey) keyFactory.generatePublic(pubKeySpec);

Signature signature = Signature.getInstance("Sha256withECDSA");
signature.initVerify(publicKey);
signature.update(messageBytes);
boolean verified = signature.verify(signatureBytes);

and this is the definition of hexStringToByteArray method:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

public static final byte[] hexStringToByteArray(final String str) {
    int len = str.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2)
        data[i / 2] = (byte) ((Character.digit(str.charAt(i), 16) << 4) + Character.digit(str.charAt(i+1), 16));
    return data;
}

what’s wrong with this code?

>Solution :

The verification is successful if the ASCII (or UTF-8) encoding of messageHex is applied and not the hex decoded messageHex, i.e. with

byte[] messageBytes = messageHex.getBytes(StandardCharsets.US_ASCII);

verification is successful.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading