簡體   English   中英

在 Android 中使用 RSA 解密 AES 密鑰

[英]Decrypt AES Key with RSA in Android

我正在嘗試使用 AES(128 位)加密一個小文件,然后使用 RSA(1024 位)加密 AES 密鑰。 這工作正常。

作為合乎邏輯的下一步,我嘗試使用 RSA 解密 AES 密鑰。

使用 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)

我的密鑰對生成邏輯 -

        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);

我的加密邏輯 -

        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);
    }

我的解密邏輯 -

        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);
    }

我改變了以下 -

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();

我正在生成一個新的密鑰對來訪問公鑰和私鑰。

感謝@president-james-moveon-polk 為我指明了正確的方向。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM