Подтвердить что ты не робот

Шифрование и расшифровка имени пользователя с помощью KeyStore в Android M и более старой версии?

Я пытаюсь зашифровать и дешифровать имя пользователя в приложении с помощью KeyStore,

Использование KeyPairGeneratorSpec для создания ключа в более старой версии, например, с 18 по 22,

KeyPairGeneratorSpec как лишенный версии 23 android M, Но Android M поддерживает KeyGenParameterSpec.

Поддерживает ли этот KeyGenParameterSpec обратную сопоставимость или как это сделать?

Я пробую кое-что вроде этого, есть ли лучшее решение для этого. Это отлично работает, как сейчас!

Во время Ciper.getInstance в шифровании и расшифровке мне нужно это сделать. есть ли один параметр "RSA/ECB/OAEPWithSHA-256AndMGF1Padding" или "RSA/ECB/PKCS1Padding", который я могу передать для обеих версий?

if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
            c =  Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
        }else{
            c =  Cipher.getInstance("RSA/ECB/PKCS1Padding");
        }

Ниже код работает отлично, как сейчас, дайте мне знать, как я могу улучшить это.

Генератор ключей:

genkey(){
KeyPairGenerator generator = KeyPairGenerator .getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
            if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
                TCLog.e(TAG,"Current version is 23(MashMello)");
                //Api level 23

                KeyGenParameterSpec spec = new  KeyGenParameterSpec.Builder(
                             keyName,
                            KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT )
                            .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
                            .build();
                generator.initialize(spec);
            }else{
                TCLog.e(TAG,"Current version is < 23(MashMello)");
                //api level 17+ 4.4.3
                KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(getActivity())
                        .setAlias(keyName)
                        .setSubject(new X500Principal("CN=Sample Name, O=Android Authority"))
                        .setSerialNumber(BigInteger.ONE)
                        .setStartDate(start.getTime())
                        .setEndDate(end.getTime())
                        .build();
                generator.initialize(spec);
            }
           KeyPair keyPair = generator.generateKeyPair();
}

Код шифрования:

doEncription(){
 try {
        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(keyName, null);
        PublicKey publicKey = (PublicKey) privateKeyEntry.getCertificate().getPublicKey();
        Cipher c;
        if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
            c =  Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
        }else{
            c =  Cipher.getInstance("RSA/ECB/PKCS1Padding");
        }

        c.init(Cipher.ENCRYPT_MODE, publicKey);
        encodedUser = c.doFinal(userName.getBytes());
        encodedPassword = c.doFinal(userPassword.getBytes());

        userName = Base64.encodeToString(encodedUser, Base64.DEFAULT);
        userPassword = Base64.encodeToString(encodedPassword, Base64.DEFAULT);
        // Log.e("MainActivity","AES Encription Error.!");
    } catch (Exception e) {
        Log.e("MainActivity", "AES Encription Error.!");
    }
}

Код дешифрования:

doDecryption(){
    try {
        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(keyName, null);
        PrivateKey privateKey = (PrivateKey) privateKeyEntry.getPrivateKey();

        Cipher c;
        if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
            c =  Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
        }else{
            c =  Cipher.getInstance("RSA/ECB/PKCS1Padding");
        }
        c.init(Cipher.DECRYPT_MODE, privateKey);
        decodedUser = c.doFinal(encodedUser);
        decodedPassword = c.doFinal(encodedPassword);

    } catch (Exception e) {
        Log.e("MainActivity", "AES Decryption Error.!");
    }

}
4b9b3361

Ответ 1

преобразование cypher зависит от параметров, которые вы даете KeyGenParameterSpec или KeyPairGeneratorSpec. Если вы хотите использовать "RSA/ECB/PKCS1Padding" в обоих случаях (Android M и ниже), измените

spec.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)

to

spec.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)

Вы можете проверить, какие алгоритмы доступны с помощью следующей части кода:

    Provider[] providers = Security.getProviders();
    for (Provider p : providers) {
        Log.d(TAG, "provider: " + p.getName());
        Set<Provider.Service> services = p.getServices();
        for (Provider.Service s : services) {
            Log.d(TAG, "--> algorithm: " + s.getAlgorithm());
        }
    }

Я избегал писать много if-else, объявляя интерфейс IKeyStoreHandler, который предоставляет все необходимые методы (добавляет/удаляет ключи, перечисляет все ключи по их псевдонимам, получает частный/открытый ключ, расшифровывает/шифрует текст) и реализует его для обоих случаев.