2

I'm working on a project that creates a PKI to get a certificate request in Android.

Right now I'm using Spongycastle for it and It's working in Android 5 and up, but on 4.X it's showing me this:

Signature SHA256WITHECDSA implementation not found
 java.security.NoSuchAlgorithmException: Signature SHA256WITHECDSA implementation not found
     at org.apache.harmony.security.fortress.Engine.notFound(Engine.java:177)
     at org.apache.harmony.security.fortress.Engine.getInstance(Engine.java:170)
     at java.security.Signature.getSignatureInstance(Signature.java:178)
     at java.security.Signature.getInstance(Signature.java:146)
     at org.spongycastle.jce.PKCS10CertificationRequest.<init>(PKCS10CertificationRequest.java:363)
     at org.spongycastle.jce.PKCS10CertificationRequest.<init>(PKCS10CertificationRequest.java:248)
     at com.unipagos.app.enrollmentprocess.EnrollmentStep5FragmentActivity.createPKI(EnrollmentStep5FragmentActivity.java:199)
     at com.unipagos.app.enrollmentprocess.EnrollmentStep5FragmentActivity.onPostCreate(EnrollmentStep5FragmentActivity.java:145)
     at android.app.Instrumentation.callActivityOnPostCreate(Instrumentation.java:1157)
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2075)
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2117)
     at android.app.ActivityThread.access$700(ActivityThread.java:134)
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1218)
     at android.os.Handler.dispatchMessage(Handler.java:99)
     at android.os.Looper.loop(Looper.java:137)
     at android.app.ActivityThread.main(ActivityThread.java:4867)
     at java.lang.reflect.Method.invokeNative(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:511)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
     at dalvik.system.NativeStart.main(Native Method)

The code for creating the cert request is this:

public String createPKI(String mdnString) {
    try {

        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
        //KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", "SC");

        ECGenParameterSpec ecGenSpec = new ECGenParameterSpec("prime256v1");
        keyPairGenerator.initialize(ecGenSpec, new SecureRandom());

        KeyPair kp =  keyPairGenerator.generateKeyPair();

        publicKey = kp.getPublic();
        privateKey = kp.getPrivate();

        PKCS10CertificationRequest kpGen = new PKCS10CertificationRequest("SHA256WITHECDSA", new X509Name(String.format("UID=%s", mdnString)), publicKey, null, privateKey);

        String certRequest = Base64.encodeToString(kpGen.getEncoded(), Base64.DEFAULT);
        certRequest = certRequest.replace("\n", "");

        return certRequest;

    } catch(Exception e) {
        if (Constants.DEBUG) {
            Log.v("Exception", e.getMessage());
        }
        e.printStackTrace();
        return null;
    }
}

The version of spongycastle I'm using is this: sc-light-jdk15on-1.47.0.2.jar and scprov-jdk15on-1.47.0.2.jar

¿Any ideas about this?

Ranbeuer
  • 167
  • 3
  • 12

2 Answers2

0

Did you add the SpongyCastle provider ?

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

Also, you will have to use this KeyPairGenerator instance:

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "SC");

To be sure you are selecting SpongyCastle as the Security Provider.

Bibu
  • 1,249
  • 2
  • 17
  • 40
0

It's cause of the default bouncy castle provider added part of the Android OS. It can be solved using any one of the below mentioned approach.

Approach 1

Replace the default OS level Bouncy castle provider with SpongyCastleProvider.

//Remove the existing bouncy castle provider initiated part of the Android OS using it's name.
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
//Add bouncy castle provider from library
Security.addProvider(org.spongycastle.jce.provider.BouncyCastleProvider());

Approach 2

And also there's one more option available. Get KeyPairGenerator instance by adding the provider instance part of the getInstance() menthod like below.

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", new org.spongycastle.jce.provider.BouncyCastleProvider());

Same works with the Bouncy castle library as well. If you're targetting the app above Android 3.0(API Level 11), Suggest to use BouncyCastle library instead of SpongyCastle as suggested by SpongyCastle library author and follow any one of the approach mentioned above with the org.bouncycastle.jce.provider.BouncyCastleProvider(). Use the below dependencies in the app gradle to include the bouncy castle library.

// Bouncy castle
implementation "org.bouncycastle:bcprov-jdk15to18:1.68"

Refer below links to get the latest version of bouncy castle provider. https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15to18

Mahendran Sakkarai
  • 8,381
  • 6
  • 44
  • 66