Bouncycastle 在 android API < 21 时失败

Bouncycastle fails in android API < 21

我正在尝试 运行 android 中的一些 spongycastle 代码:

    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());
    }

在 API 版本 21+ 中,它按预期工作。

在 API 版本 18 中,它在调试中工作。在发行版中,它在 generator.generateKeyPair()java.lang.IllegalArgumentException: Invalid point.

功能中失败

在 API 版本 16 中,它在函数 Jwts.builder().signWith() 中失败 io.jsonwebtoken.security.SignatureException: Invalid Elliptic Curve PrivateKey. can't recognise key type in ECDSA based signer

知道我做错了什么吗?

编辑:我显然已经通过从 spongycastle 切换到 bouncycastle 解决了这个问题。

在我的 build.gradle 中,我更改了这个:

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

对此:

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

在我的代码中我去掉了这一行:

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

并添加了这些行:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

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

并且我将提供商从 "SC" 更改为 "BC"

现在我的代码可以正常工作,适用于 android API.

的所有版本

我现在关心的是这个 link...

的评论

Spongy Castle: is it obsolete?

...海绵城堡作者:

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.

这到底是什么意思?它会导致我上面的代码在某些设备上出现故障吗?

使用充气城堡:

dependencies {
    // https://mvnrepository.com/artifact/org.bouncycastle
    implementation "org.bouncycastle:bcprov-jdk15on:1.60"
    implementation "org.bouncycastle:bcpkix-jdk15on:1.60"
}