1. The purpose of this post
I would demo how to solve this error when using SecureRandom algorithm in android studio,for example, if we use google authenticator library , it would generate random number by using the SecureRandom object,but when we run the app, this error occurs:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.tom, PID: 21824
java.lang.ExceptionInInitializerError
at com.tom.otp.OtpLoginActivity.onCreate(OtpLoginActivity.java:56)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: com.warrenstrange.googleauth.GoogleAuthenticatorException: Could not initialise SecureRandom with the specified provider: SUN. Another provider can be chosen setting the com.warrenstrange.googleauth.rng.algorithmProvider system property.
at com.warrenstrange.googleauth.ReseedingSecureRandom.buildSecureRandom(ReseedingSecureRandom.java:118)
at com.warrenstrange.googleauth.ReseedingSecureRandom.<init>(ReseedingSecureRandom.java:84)
at com.warrenstrange.googleauth.GoogleAuthenticator.<init>(GoogleAuthenticator.java:151)
at com.tom.otp.OtpLoginPresenter.<clinit>(OtpLoginPresenter.java:45)
at com.tom.otp.OtpLoginActivity.onCreate(OtpLoginActivity.java:56)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.security.NoSuchProviderException: no such provider: SUN
at sun.security.jca.GetInstance.getService(GetInstance.java:83)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
at java.security.SecureRandom.getInstance(SecureRandom.java:348)
at com.warrenstrange.googleauth.ReseedingSecureRandom.buildSecureRandom(ReseedingSecureRandom.java:101)
at com.warrenstrange.googleauth.ReseedingSecureRandom.<init>(ReseedingSecureRandom.java:84)
at com.warrenstrange.googleauth.GoogleAuthenticator.<init>(GoogleAuthenticator.java:151)
at com.tom.otp.OtpLoginPresenter.<clinit>(OtpLoginPresenter.java:45)
at com.tom.otp.OtpLoginActivity.onCreate(OtpLoginActivity.java:56)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
2. Environments
Android Studio 3.x
gradle wrapper version:
distributionUrl=https://services.gradle.org/distributions/gradle-5.4.1-all.zip
project build.gradle
classpath ‘com.android.tools.build:gradle:3.5.0’
google auth library version:
implementation group: ‘com.warrenstrange’, name: ‘googleauth’, version: ‘1.4.0’
3. Solution and Code
Because by default, the library uses ‘SUN’ provider as the default SecureRandom algorithm provider, which is deprecated in the android system. So you can change it like this:
Provider [] secureRandomProviders = Security . getProviders ( "SecureRandom.SHA1PRNG" );
System . setProperty ( "com.warrenstrange.googleauth.rng.algorithmProvider" , secureRandomProviders [ 0 ]. getName ());
The code above just lists all the providers in the android system, and choose the first one as the provider.
Clean,rebuild and run the app, everything works.