1

i am trying to run some spongycastle code in android:

    try {
        Security.addProvider(new org.spongycastle.jce.provider.BouncyCastleProvider());
        ECGenParameterSpec spec = new ECGenParameterSpec("P-256");
        KeyPairGenerator generator = KeyPairGenerator.getInstance("ECDSA", "SC");
        generator.initialize(spec, new SecureRandom());
        KeyPair keyPair = generator.generateKeyPair();
        ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();
        ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();
        String publicKeyStr = publicKey.getW().getAffineX().toString() + ":" + publicKey.getW().getAffineY().toString();
        Log.d(TAG, publicKeyStr);
        Calendar c = Calendar.getInstance();
        Date d0 = c.getTime();
        c.add(Calendar.DATE, 1);
        Date expiry = c.getTime();
        String token = Jwts.builder()
                .setIssuedAt(d0)
                .setSubject("00000000-0000-0000-0000-000000000001")
                .setExpiration(expiry)
                .signWith(privateKey, SignatureAlgorithm.ES256).compact();
        Log.d(TAG, token);
    } catch (Exception e) {
        Log.d(TAG, e.toString());
    }

in API version 21+, it works as expected.

in API version 18, it works in debug. in release, it fails in function generator.generateKeyPair() with java.lang.IllegalArgumentException: Invalid point.

in API version 16, it fails in function Jwts.builder().signWith() with io.jsonwebtoken.security.SignatureException: Invalid Elliptic Curve PrivateKey. can't recognise key type in ECDSA based signer.

any idea what i am doing wrong?

edit: i have apparently fixed the problem by switching from spongycastle to bouncycastle.

in my build.gradle i changed this:

implementation 'com.madgag.spongycastle:core:1.58.0.0'
implementation 'com.madgag.spongycastle:prov:1.58.0.0'

to this:

implementation 'org.bouncycastle:bcpkix-jdk15on:1.60'

and in my code i got rid of this line:

Security.addProvider(new org.spongycastle.jce.provider.BouncyCastleProvider());

and added these lines:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
Security.insertProviderAt(new BouncyCastleProvider(), 1);

and i changed the provider from "SC" to "BC".

and now my code works as i would like, for all versions of the android API.

my concern now is the comment at this link...

Spongy Castle: is it obsolete?

...by the author of spongycastle:

Why might Spongy Castle not be obsolete?

...

even on post-Android 3.0 devices, device manufacturers are not above carelessly bundling libraries, it's possible that Bouncy Castle may still be bundled on some obscure devices.

what does that mean exactly? could it cause my code above to malfunction on certain devices?

erik
  • 83
  • 6
  • I'm not sure it matters, but just to verify this which version of the spongycastle library are you using? – President James K. Polk May 29 '19 at 17:01
  • thanks for getting back to me. i was running spongycastle version 1.58. i have apparently fixed the problem by switching to bouncycastle 1.60. is that a good solution? i edited my OP with additional information. – erik May 29 '19 at 20:25
  • Bouncycastle 1.60 (or 1.61 which is current now) should be fine. I wouldn't worry about rtley's concern about careless bundling, I think it is very unlikely and yours would not be the only app affected if that ever happened. – President James K. Polk May 29 '19 at 20:41

1 Answers1

0

use bouncy castle:

dependencies {
    // https://mvnrepository.com/artifact/org.bouncycastle
    implementation "org.bouncycastle:bcprov-jdk15on:1.60"
    implementation "org.bouncycastle:bcpkix-jdk15on:1.60"
}
Martin Zeitler
  • 1
  • 19
  • 155
  • 216