j2objc: java.security.Signature.verify method call failing with EXC_BAD_ACCESS error

I’m using version 1.3.1 of the J2ObjC library. I’m attempting to verify a SHA256WithRSA signature with the java.security.Signature class as follows:

BigInteger publicExponent = new BigInteger(PUBLIC_EXPONENT_BYTES);
BigInteger modulus = new BigInteger(MODULUS_BYTES);

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
KeySpec keySpec = new RSAPublicKeySpec(modulus, publicExponent);
PublicKey publicKey = keyFactory.generatePublic(keySpec);

Signature signature = Signature.getInstance("SHA256WithRSA");
signature.initVerify(publicKey);
signature.update(dataBytes);

boolean signatureValid = signature.verify(signatureBytes);

I’ve verified the Java code and it runs okay. The translated code however falls over on the last line above with a EXC_BAD_ACCESS error. I have tried it both in the Simulator as well as on a real device.

I’m guessing that the code should run okay since it has translated from Java to Objective-C without issues. Is this a bug in the J2ObjC library or should I refrain from doing SHA256WithRSA signature verification in the translated code?

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 15 (7 by maintainers)

Commits related to this issue

Most upvoted comments

Argh! Creating a public key using your instructions failed to decode using your Gist. It looks like the issue is that RSA public keys can be encoded using DER in multiple legal ways. So hard-wiring the byte offsets to specific sequence patterns will work for certificates from one source and may fail from others.

I’m going to try what’s hopefully an easier and more robust solution: decode the certificate using sun.security.util.DerInputStream https://github.com/google/j2objc/blob/master/jre_emul/android/platform/libcore/ojluni/src/main/java/sun/security/util/DerInputStream.java, then create the secKey using a RSAPublicKeySpec with the modulus and exponent values from decoding. Wish me luck!

On Wed, Jun 7, 2017 at 7:58 AM Adil Hussain notifications@github.com wrote:

@tomball https://github.com/tomball: According to this http://blog.flirble.org/2011/01/05/rsa-public-key-openssl-ios Blog post you can generate a public key that contains the header that needs to be stripped as follows:

$ openssl genrsa -out testkeypair.pem 1024 $ openssl rsa -in testkeypair.pem -pubout -outform PEM -out testpublic.pem

In my project I created a keystore file with the following command…

$ keytool -genkey -alias MyAlias -keyalg RSA -keystore MyKeystore.jks -keysize 2048

… and then I used the java.security APIs to extract the public key byte array which I feed into the iOS code and which contains the header that needed to be stripped, as follows:

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(keyStoreFileInputStream, keyStorePasswordCharArray);

Certificate certificate = keyStore.getCertificate(“MyAlias”); PublicKey publicKey = certificate.getPublicKey();

byte[] publicKeyBytes = publicKey.getEncoded();

Not sure if it’s useful to you but I also found the following keytool command which you can use to extract the public certificate from the keystore file:

$ keytool -export -keystore MyKeystore.jks -alias MyAlias -file MyCertificate.cer

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/google/j2objc/issues/858#issuecomment-306821631, or mute the thread https://github.com/notifications/unsubscribe-auth/AC2kr6Ap5EYUHuvzIvmTkvyKQ6oNaXjvks5sBrqkgaJpZM4Nj9e3 .

Fixed in current source, thanks for your help!

Thanks! I was most of the way toward a similar solution last night (we may have started from a similar StackOverflow question), but your code works and is simpler and easier to read. I’ll keep this code RSA-specific for now by calling it in IosRSAKey.IosRSAPublicKey(RSAPublicKeySpec). One thing that needs to be added is determining the key size from the RSAPublicKeySpec, which should be simple thanks to this answer. As a sanity test, is the size of your test key the size of its modulus (publicKey.getModulus().bitLength())?