Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android解密错误_Java_Android_Encryption_Public Key Encryption_Private Key - Fatal编程技术网

Java Android解密错误

Java Android解密错误,java,android,encryption,public-key-encryption,private-key,Java,Android,Encryption,Public Key Encryption,Private Key,我试图在我的Android应用程序中加密和解密字符串,但我一直收到一个InvalidKeyException错误 这是我的密码: //生成密钥方法 public void generateKeys() { Calendar cal = Calendar.getInstance(); Date now = cal.getTime(); cal.add(Calendar.YEAR, 25); Date end = cal.getTime(); KeyPair

我试图在我的Android应用程序中加密和解密字符串,但我一直收到一个InvalidKeyException错误

这是我的密码:

//生成密钥方法

public void generateKeys() {
    Calendar cal = Calendar.getInstance();
    Date now = cal.getTime();
    cal.add(Calendar.YEAR, 25);
    Date end = cal.getTime();

    KeyPairGenerator kpg = null;
    try {
        kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchProviderException e) {
        e.printStackTrace();
    }
    try {
        kpg.initialize(new KeyPairGeneratorSpec.Builder(context)
                .setAlias(KEY_ALIAS)
                .setStartDate(now)
                .setEndDate(end)
                .setSerialNumber(BigInteger.valueOf(1))
                .setSubject(new X500Principal("CN=" + KEY_ALIAS))
                .build());
    } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    }

    KeyPair kp = kpg.generateKeyPair();

    KeyStore ks = null;
    try {
        ks = KeyStore.getInstance("AndroidKeyStore");
        ks.load(null);
        Enumeration<String> aliases = ks.aliases();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    } catch (CertificateException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    KeyStore.Entry entry = null;
    try {
        entry = ks.getEntry(KEY_ALIAS, null);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (UnrecoverableEntryException e) {
        e.printStackTrace();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    }
    if (!(entry instanceof KeyStore.PrivateKeyEntry)) {
        Log.e(LOG_TAG, "Not an instance of PrivateKeyEntry.");
    }
    else{
        privKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
        pubKey = ((KeyStore.PrivateKeyEntry) entry).getCertificate().getPublicKey();
    }

}
//解密方法

private String encryptString(String value){
    byte[] encodedBytes = null;
    try {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
        cipher.init(Cipher.ENCRYPT_MODE,  pubKey);
        encodedBytes = cipher.doFinal(value.getBytes());
    } catch (Exception e) {
        e.printStackTrace();
    }

    return Base64.encodeToString(encodedBytes, Base64.DEFAULT);
}
private String decryptString(String value){
    byte[] decodedBytes = null;
    try {
        Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
        c.init(Cipher.DECRYPT_MODE,  privKey);
        decodedBytes = c.doFinal(Base64.decode(value, Base64.DEFAULT));
    } catch (Exception e) {
        e.printStackTrace();
        Log.e("Error", "Error = " + e);
        return "SECURE_FAILURE";
    }

    return new String(decodedBytes);
}
//测试代码

    generateKeys();
    String encrypted = encryptString("Hello World");
    Log.e("Encrypt", "encrypted = " + encrypted);
    String decrypted = decryptString(encrypted);
    Log.e("Decrypt", "decrypted = " + decrypted);
看起来加密工作正常,因为它打印出如下内容:

Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround");
加密的= SBA2IWKQBDL7NTA9xVTJD/viYDdpx9fLRYTSZ8UQzdBy3QLqzkswBY21ErH7FPza3vZys4E4PZw uxaGkRz0aC0FLqsYlbpcJernGm5+D5lRcBOaZmgkNY9pMf0YP75cBbcJdcmb1rDaH40nCRDnEoXv RGESJRQT6P0NMZLZQDD9KO3TQFEXWGSERVAWXPNTRDBMGE4I/09418jM5Ock5eayfOuv/STwEy6 Ecd56UjFH63h+gP6ed2aMDhBVeExMxvdloY+VnsAxS5Dkoc2GdaljtjRuPK48HQASoJK8EwAMNpz

但是,当我尝试解密时,会出现以下错误:

java.security.InvalidKeyException:需要RSA私钥或公钥


我不明白为什么我会得到这个例外?有人能帮忙吗?

尝试使用其他提供商,如:

Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround");
这对我很有用:

private Cipher getCipher() {
    try {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { // below android m
            return Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL"); // error in android 6: InvalidKeyException: Need RSA private or public key
        }
        else { // android m and above
            return Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround"); // error in android 5: NoSuchProviderException: Provider not available: AndroidKeyStoreBCWorkaround
        }
    } catch(Exception exception) {
        throw new RuntimeException("getCipher: Failed to get an instance of Cipher", exception);
    }
}
Cipher.getInstance("RSA/ECB/PKCS1Padding")
private Cipher getCipher(){
试一试{
如果(Build.VERSION.SDK_INT
删除提供商对我来说很有效:

private Cipher getCipher() {
    try {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { // below android m
            return Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL"); // error in android 6: InvalidKeyException: Need RSA private or public key
        }
        else { // android m and above
            return Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidKeyStoreBCWorkaround"); // error in android 5: NoSuchProviderException: Provider not available: AndroidKeyStoreBCWorkaround
        }
    } catch(Exception exception) {
        throw new RuntimeException("getCipher: Failed to get an instance of Cipher", exception);
    }
}
Cipher.getInstance("RSA/ECB/PKCS1Padding")

From:“此方法遍历已注册的安全提供程序列表,从最首选的提供程序开始。将返回一个新的密码对象,该对象封装了支持指定算法的第一个提供程序的CipherSpi实现。”

幸运吗?我在安卓棉花糖中遇到了同样的异常。我通过使用不同的提供商修复了它。。。请参阅下面我的答案。除非有理由需要非对称加密(RSA)公钥/私钥,否则只需使用对称加密,如AES。对称加密是数据加密的一般选择。非对称加密数据长度仅限于密钥大小,速度非常慢且不安全。虽然有一些解释会很好,但对我来说是可行的。请看“lanna blue”的答案,您必须根据Android版本更改RSA加密的提供商名称!否则你会出错!陛下如果我们在棒棒糖上创建了一个公共和一个私有的RSA密钥,然后用户将他的Android操作系统升级为棉花糖,会怎么样。我们的方法将返回不同的提供程序-它是否适用于以前生成的RSA密钥?@KirillKarmazin我认为,如果使用相同的算法、密码和填充,无论使用什么提供程序,结果都应该是相同的。我还认为,我们可以跳过第二个参数,让我们选择提供程序