Расшифровать ключ AES с помощью RSA в Android - PullRequest
2 голосов
/ 09 мая 2020

Я пытаюсь зашифровать небольшой файл с помощью AES (128 бит), а затем зашифровать ключ AES с помощью RSA (1024 бит). Это отлично работает.

В качестве следующего логического шага я пытаюсь расшифровать ключ AES с помощью RSA.

Расшифровка с помощью RSA возвращает 128-байтовый блок, но мой ключ AES имеет длину всего 16 байтов. После исследования я прочитал, что мне нужно использовать RSA с Padding, поэтому я использовал RSA / ECB / PKCS1Padding .

Но это всегда дает мне следующее исключение -

javax.crypto.BadPaddingException: error:04000089:RSA routines:OPENSSL_internal:PKCS_DECODING_ERROR
at com.android.org.conscrypt.NativeCrypto.RSA_private_decrypt(Native Method)
at com.android.org.conscrypt.OpenSSLCipherRSA$DirectRSA.doCryptoOperation(OpenSSLCipherRSA.java:402)
at com.android.org.conscrypt.OpenSSLCipherRSA.engineDoFinal(OpenSSLCipherRSA.java:314)
at javax.crypto.Cipher.doFinal(Cipher.java:2055)

My KeyPair generation logi c -

        KeyPairGenerator keyGen = null;
        try {
            keyGen = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        keyGen.initialize(1024);
        byte[] publicKey = keyGen.genKeyPair().getPublic().getEncoded();

        byte[] privateKey = keyGen.genKeyPair().getPrivate().getEncoded();


        Util.save("privateKey", rsa.encryptBASE64(privateKey), this);
        Util.save("publicKey", rsa.encryptBASE64(publicKey), this);

My Encryption logi c -

        public static byte[] encryptByPublicKey(byte[] data, String key)
            throws Exception {

        byte[] keyBytes = decryptBASE64(key);


        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key publicKey = keyFactory.generatePublic(x509KeySpec);


        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        return cipher.doFinal(data);
    }

My Decryption logi c -

        public static byte[] decryptByPrivateKey(byte[] data, String key)
            throws Exception {

        byte[] keyBytes = decryptBASE64(key);


        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);


        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        return cipher.doFinal(data);
    }

Любая помощь будет принята с благодарностью.

Может ли кто-нибудь также посоветовать мне, как преобразовать расшифрованный блок RSA в ключ AES?

Чтобы проверить, что я делаю в своем коде. Шифрование и дешифрование идут в обратном направлении -

String aesKeyCipherBase64 = rsa.encryptBASE64(rsa.encryptByPublicKey(secretKey.getEncoded(), myPublicKeyString));

byte[] aesKeyRecovered = rsa.decryptByPrivateKey(rsa.decryptBASE64(aesKeyCipherBase64),myPrivateKeyString);

Метод утилит Base64 -

public static byte[] decryptBASE64(String key)  {
        return Base64.decode(key, Base64.NO_PADDING|Base64.NO_WRAP|Base64.NO_PADDING|Base64.URL_SAFE);
    }

public static String encryptBASE64(byte[] key)  {
        return Base64.encodeToString(key, Base64.NO_PADDING|Base64.NO_WRAP|Base64.NO_PADDING|Base64.URL_SAFE);
    }
       public static void save(String key, String value, Activity activity) {


        SharedPreferences sharedPref = activity.getSharedPreferences("myapp",Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPref.edit();
        editor.putString(key, value);
        editor.commit();
    }
        String myPublicKeyString = Util.getPublicKey(this);
        String myPrivateKeyString = Util.getPrivateKey(this);
    public static String getPrivateKey(Activity activity) {

        SharedPreferences sharedPref = activity.getSharedPreferences("myapp",Context.MODE_PRIVATE);
        return sharedPref.getString("privateKey", null);
    }

    public static String getPublicKey(Activity activity) {

        SharedPreferences sharedPref = activity.getSharedPreferences("myapp",Context.MODE_PRIVATE);
        return sharedPref.getString("publicKey", null);
    }

1 Ответ

2 голосов
/ 09 мая 2020

Я изменил следующее -

byte[] publicKey = keyGen.genKeyPair().getPublic().getEncoded();

byte[] privateKey = keyGen.genKeyPair().getPrivate().getEncoded();

на -

KeyPair kp = keyGen.genKeyPair();

byte[] publicKey = kp.getPublic().getEncoded();
byte[] privateKey = kp.getPrivate().getEncoded();

Я генерировал новую пару ключей для доступа к publi c и закрытому ключу.

Спасибо @ President-james-moveon-polk за то, что указал мне в правильном направлении.

...