android - 支持的算法错误?

标签 android encryption

我有在 Android 中使用的加密/解密密码。它在 Android 4.4 上运行良好

static void setKey(byte[] keybytes, byte[] iv) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
    key = new SecretKeySpec(keybytes, "AES");
    ivspec = new IvParameterSpec(iv);
    encryptcipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    encryptcipher.init(Cipher.ENCRYPT_MODE, key,ivspec);

    decryptcipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    decryptcipher.init(Cipher.DECRYPT_MODE, key,ivspec);        
}

但是,每当我在 Android 4.3 上运行它时,我都会收到此错误

07-25 17:17:25.917: W/System.err(27544): java.lang.RuntimeException: java.security.NoSuchAlgorithmException: SecureRandom SHA1PRNG implementation not found
07-25 17:17:25.927: W/System.err(27544):    at java.security.SecureRandom.<init>(SecureRandom.java:100)
07-25 17:17:25.927: W/System.err(27544):    at javax.crypto.Cipher.init(Cipher.java:564)
07-25 17:17:25.927: W/System.err(27544):    at com.chatads.sdk.bm.a(SourceFile:56)
07-25 17:17:25.927: W/System.err(27544):    at com.chatads.sdk.x.a(SourceFile:241)
07-25 17:17:25.927: W/System.err(27544):    at com.chatads.sdk.ax.run(SourceFile:66)
07-25 17:17:25.927: W/System.err(27544):    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390)
07-25 17:17:25.927: W/System.err(27544):    at java.util.concurrent.FutureTask.run(FutureTask.java:234)
07-25 17:17:25.927: W/System.err(27544):    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:153)
07-25 17:17:25.927: W/System.err(27544):    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:267)
07-25 17:17:25.927: W/System.err(27544):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
07-25 17:17:25.927: W/System.err(27544):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
07-25 17:17:25.927: W/System.err(27544):    at java.lang.Thread.run(Thread.java:841)
07-25 17:17:25.927: W/System.err(27544): Caused by: java.security.NoSuchAlgorithmException: SecureRandom SHA1PRNG implementation not found
07-25 17:17:25.927: W/System.err(27544):    at java.security.Provider$Service.newInstance(Provider.java:1000)
07-25 17:17:25.927: W/System.err(27544):    at java.security.SecureRandom.<init>(SecureRandom.java:97)
07-25 17:17:25.927: W/System.err(27544):    ... 11 more
07-25 17:17:25.927: W/System.err(27544): Caused by: java.lang.IllegalAccessException: access to class not allowed
07-25 17:17:25.927: W/System.err(27544):    at java.lang.Class.newInstanceImpl(Native Method)
07-25 17:17:25.927: W/System.err(27544):    at java.lang.Class.newInstance(Class.java:1130)
07-25 17:17:25.927: W/System.err(27544):    at java.security.Provider$Service.newInstance(Provider.java:998)
07-25 17:17:25.927: W/System.err(27544):    ... 12 more

我运行了这段代码

Provider[] providers = Security.getProviders();
for (Provider provider : providers) {
    Log.i("CRYPTO","provider: "+provider.getName());
    Set<Provider.Service> services = provider.getServices();
    for (Provider.Service service : services) {
        Log.i("CRYPTO","  algorithm: "+service.getAlgorithm());
    }
}

在这里找到What crypto algorithms does Android support?

所有 AES、AES/CBC/PKCS5Padding 和 SHA1PRNG 都出现在输出中。这是一个Android错误吗?还是我做错了什么?

最佳答案

我想出了如何保证我需要的算法的存在。首先我下载了​​Spongey Castle并将其添加到我的构建路径中

我使用此代码将 SC 添加为提供者

static {
    Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1);
}

这样做之后我仍然有和以前一样的错误所以然后将我的代码更改为

static void setKey(byte[] keybytes, byte[] iv) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, NoSuchProviderException
{
    /**
     * crypto is specifically stated here because without using AndroidOpenSSL for the SHA1PRNG breaks on some phones,
     * PRNGFixes.apply() should be called if using this
     * https://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html 
     */
    random = SecureRandom.getInstance("SHA1PRNG", "Crypto");
    key = new SecretKeySpec(keybytes, "AES");
    ivspec = new IvParameterSpec(iv);
    encryptcipher = Cipher.getInstance("AES/CFB/NoPadding", "SC");
    encryptcipher.init(Cipher.ENCRYPT_MODE, key, ivspec, random);

    decryptcipher = Cipher.getInstance("AES/CFB/NoPadding", "SC");
    decryptcipher.init(Cipher.DECRYPT_MODE, key, ivspec, random);       
}

解决了我所有的问题,但是使用加密存在安全问题所以我下载了在 https://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html 找到的 PRNGFixes并在我使用加密库之前在应用程序的其他地方调用了 apply

关于android - 支持的算法错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25001552/

相关文章:

java - 在库项目中使用库项目的正确 values/strings.xml

java - 检查项目中是否使用图像

android - 以底部中心为轴心点缩放 ImageView

javascript - 使用带有十六进制编码的 crypto-js 加密字符串以使其 url 友好

javascript - 使用cordova阻止android编辑栏

java - 尝试使用 HtmlCleaner 清理 HTML 时,AsyncTask 不执行

c# - 如何使用 Rijndael 在 iOS 中加密 c# 中的解密字符串

python-3.x - 在python中使用 key 加密消息

java - Java 中基于 AES-256 密码的加密/解密

PHP PDO 加密/ssl 数据层