2

In my app I need to verify a signature. An example is below. It works perfectly on Android 6 and older versions but just recently I noticed that it doesn't work on Android 7 or 8. When I run verifyData() I get this exception: java.security.SignatureException: error decoding signature bytes. at com.android.org.bouncycastle.jcajce.provider.asymmetric.util.DSABase.engineVerify(DSABase.java:82) at java.security.Signature$Delegate.engineVerify(Signature.java:1380) at java.security.Signature.verify(Signature.java:806)

What has been changed in these Android version that I don't know? How to verify signatures on Android 7 or later version?

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

import java.io.Reader;
import java.io.StringReader;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;

public class Test {

    static final String PUBLIC_KEY =
            "-----BEGIN PUBLIC KEY-----\n" +
                    "MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEXMHnQfWiM4oCaLfx296llgz7iaVv\n" +
                    "avMPppkzVNZAxtlNLhFlXnNWD0Mw9yzP8/Go\n" +
                    "-----END PUBLIC KEY-----\n";

    static final String DATA = "0443607A263B8001484E4C310100010561186AF1398003000000000000000000000001";

    static final String SIGNATURE = "303402181938B3C6FE3EFE75E1B1DF42D8E54055E07D6A5542E9ED3A021816AB6B9D1E5AF55E0E3E0B3E1A4DEA5EC4A120AFC6D51FE60000000000000000000000000000";

    static boolean verifyData() throws Exception {
        PublicKey pk = getPublicKey();
        byte[] data = hexToBytes(DATA);
        byte[] signatureBytes = hexToBytes(SIGNATURE);

        Signature signature = Signature.getInstance("SHA256withECDSA", "BC");
        signature.initVerify(pk);
        signature.update(data);
        return signature.verify(signatureBytes);
    }

    static PublicKey getPublicKey() throws Exception {
        Security.addProvider(new BouncyCastleProvider());
        Reader reader = new StringReader(PUBLIC_KEY);
        PemObject pemObject = new PemReader(reader).readPemObject();
        KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(pemObject.getContent());
        PublicKey key = keyFactory.generatePublic(x509EncodedKeySpec);
        return key;
    }

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

}

Dependency I use: compile group: 'org.bouncycastle', name: 'bcprov-jdk16', version: '1.46'

Egis
  • 5,081
  • 5
  • 39
  • 61

0 Answers0