Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.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
Android RSA解密错误?_Android_Encryption_Rsa - Fatal编程技术网

Android RSA解密错误?

Android RSA解密错误?,android,encryption,rsa,Android,Encryption,Rsa,我尝试获取一对密钥(公共和私有)来加密/解密文本。 对于加密,没有问题。对于解密,我从一天起就犯了一个错误,我不明白为什么 这是代码的相关部分: static void createKey(Context context) { try { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore"); Calendar start = Calendar.g

我尝试获取一对密钥(公共和私有)来加密/解密文本。 对于加密,没有问题。对于解密,我从一天起就犯了一个错误,我不明白为什么

这是代码的相关部分:

    static void createKey(Context context) {
    try {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
        Calendar start = Calendar.getInstance(Locale.ITALIAN);
        Calendar end = Calendar.getInstance(Locale.ITALIAN);
        end.add(Calendar.YEAR, 10);
        AlgorithmParameterSpec spec = null;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            spec = new KeyPairGeneratorSpec.Builder(context)
                    .setAlias(BuildConfig.APPLICATION_ID)
                    .setSubject(new X500Principal("CN=Sample Name, O=Android Authority"))
                    .setSerialNumber(BigInteger.ONE)
                    //.setStartDate(start.getTime())
                    //.setEndDate(end.getTime())
                    .build();
        } else {
            spec = new KeyGenParameterSpec.Builder(BuildConfig.APPLICATION_ID,KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                    .setCertificateSubject(new X500Principal("CN=Sample Name, O=Android Authority"))
                    .setDigests(KeyProperties.DIGEST_SHA256)
                    .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
                    .setCertificateSerialNumber(BigInteger.valueOf(1337))
                    .setCertificateNotBefore(start.getTime())
                    .setCertificateNotAfter(end.getTime())
                    .setRandomizedEncryptionRequired(false)
                    .build();
        }
        kpg.initialize(spec);
        KeyPair kp = kpg.generateKeyPair();
        // END_INCLUDE(create_spec)
        Log.d(TAG, "createKey Public Key is: " + kp.getPublic());
        Log.d(TAG, "createKey Private Key is: " + kp.getPrivate());
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchProviderException e) {
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    }
}


public static String encrypt(Context context, String text) {
    if(text == null || text.isEmpty()) {
        return null;
    }
    KeyStore keyStore = null;
    try {
        keyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null);
        PublicKey publicKey = keyStore.getCertificate(BuildConfig.APPLICATION_ID).getPublicKey();

        Cipher input = getCipher();
        input.init(Cipher.ENCRYPT_MODE, publicKey);//, ivspec);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        CipherOutputStream cipherOutputStream = new CipherOutputStream(
                outputStream, input);
        cipherOutputStream.write(text.getBytes("UTF-8"));
        cipherOutputStream.close();

        byte [] vals = outputStream.toByteArray();
        return Base64.encodeToString(vals, Base64.DEFAULT);
    } catch (Exception e) {
        Log.e(TAG, Log.getStackTraceString(e));
    }
    return null;
}

public static String decrypt(Context context, String encryptedText) {
    KeyStore keyStore = null;
    try {
        keyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null);
        KeyStore.Entry entry = keyStore.getEntry(BuildConfig.APPLICATION_ID, null);
        PrivateKey privateKey = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey();
        PublicKey publicKey = keyStore.getCertificate(BuildConfig.APPLICATION_ID).getPublicKey();

        Cipher output = getCipher();
        output.init(Cipher.DECRYPT_MODE, privateKey);//, ivspec);

        CipherInputStream cipherInputStream = new CipherInputStream(
                new ByteArrayInputStream(Base64.decode(encryptedText, Base64.DEFAULT)), output);
        ArrayList<Byte> values = new ArrayList<>();
        int nextByte;
        while ((nextByte = cipherInputStream.read()) != -1) {
            values.add((byte)nextByte);
        }

        byte[] bytes = new byte[values.size()];
        for(int i = 0; i < bytes.length; i++) {
            bytes[i] = values.get(i).byteValue();
        }

        return new String(bytes, 0, bytes.length, "UTF-8");

    } catch (Exception e) {
        Log.e(TAG, Log.getStackTraceString(e));
    }
    return null;
}

static Cipher getCipher() throws Exception {
    return Cipher.getInstance("RSA/ECB/PKCS1Padding");
}

您对此有什么想法吗?

似乎每次都在创建密钥对。在创建密钥之前,请尝试检查密钥是否存在

if (!keyStore.containsAlias(ALIAS_RSA)) {
    createKeys();
} else {
    retrieveKeys();
}

包含完整的堆栈跟踪可能会有所帮助。还有,你在哪个版本的Android上遇到了这个错误?谢谢你的回复James,我已经编辑了我的问题,包括完整的堆栈跟踪。已经控制它了:if(!haveKey()){createKey(context);if(!haveKey())return null;}我已经检查了只在第一次调用createKey函数的情况,谢谢你的回复!看看setSignaturePaddings方法。它缝合它应该只用于签名/验证,而不是使用setEncryptionPaddings
if (!keyStore.containsAlias(ALIAS_RSA)) {
    createKeys();
} else {
    retrieveKeys();
}