2017-06-01 500 views
1

我想在我的項目上使用RSA/AES文件加密。我用rsa製作了一對私鑰/公鑰和一個AES密鑰,之後,我將用公鑰加密AES密鑰。最後我用私有RSA密鑰解密AES加密的密鑰。javax.crypto.BadPaddingException:解密錯誤,當我嘗試使用私鑰解密RSA字符串

這是代碼: RSA密鑰:

public class EncriptionRSAKey { 
    public static final int RSA_Key_Size = 512; // dimensione chiave RSA 
    private PrivateKey privKey;// chiave privata 
    private PublicKey pubKey;// chiave pubblica 

    /** 
    * Costruttore che genera una chiave privata e una pubblica in RSA 
    * @throws NoSuchAlgorithmException 
    */ 
    public EncriptionRSAKey() throws NoSuchAlgorithmException{ 
     KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); 
     keyGen.initialize(RSA_Key_Size); 
     privKey = keyGen.genKeyPair().getPrivate(); 
     pubKey = keyGen.genKeyPair().getPublic(); 
    } 


    /** 
    * Decripta una chiave RSA cifrata con una chiave pubblica 
    * @param data chiave AES 
    * @return 
    * @throws NoSuchAlgorithmException 
    * @throws NoSuchPaddingException 
    * @throws InvalidKeyException 
    * @throws IllegalBlockSizeException 
    * @throws BadPaddingException 
    */ 
    public SecretKey decryptAESKey(byte[] data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException 
    { 
     SecretKey key = null; 
     Cipher cipher = Cipher.getInstance("RSA");; 
     cipher.init(Cipher.DECRYPT_MODE, privKey); // inizializza il cipher 
     key = new SecretKeySpec (cipher.doFinal(data), "AES"); // genera la chiave AES 
     return key; 
    } 

    /** 
    * Restituisce la chiave pubblica 
    * @return pubKey chiave pubblica 
    */ 
    public PublicKey getPubKey() { 
     return pubKey; 
    } 
For AES key: 

    public class EncriptionAESKey { 
    public static final int AES_Key_Size = 256; // dimensione chiave AES 

    /** 
    * Genera una chiave AES 
    * @return aesKey Chiave AES 
    * @throws NoSuchAlgorithmException 
    */ 
    public static SecretKey makeAESKey() throws NoSuchAlgorithmException { 
     KeyGenerator keyGen = KeyGenerator.getInstance("AES"); 
     keyGen.init(AES_Key_Size); 
     return keyGen.generateKey(); 
    } 

    /** 
    * Cifra una chiave AES data una chiave pubblica RSA 
    * @param skey Chiave AES da cifrare 
    * @param publicKey Chiave RSA pubblica 
    * @return key AES cifrato con RSA 
    * @throws InvalidKeyException 
    * @throws NoSuchAlgorithmException 
    * @throws NoSuchPaddingException 
    * @throws IllegalBlockSizeException 
    * @throws BadPaddingException 
    */ 
    public static byte[] EncryptSecretKey (SecretKey skey, PublicKey publicKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException 
    { 
     Cipher cipher = null; 
     byte[] key = null; 
     // initialize the cipher with the user's public key 
     cipher = Cipher.getInstance("RSA"); 
     cipher.init(Cipher.ENCRYPT_MODE, publicKey); 
     key = cipher.doFinal(skey.getEncoded()); 
     return key; 
    } 

在這條線測試類

public class EncriptionTest { 

    @Test 
    public void testAESEncription() { 
     try { 
      EncriptionRSAKey rsa = new EncriptionRSAKey(); 
      SecretKey aes = EncriptionAESKey.makeAESKey(); 
      byte[] aesEnc = EncriptionAESKey.EncryptSecretKey(aes, rsa.getPubKey()); 
      assertEquals(rsa.decryptAESKey(aesEnc),aes); 


     } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) { 
      e.printStackTrace(); 
      fail(); 
     } 
    } 

byte[] aesEnc = EncriptionAESKey.EncryptSecretKey(aes, rsa.getPubKey());

Gives me this Exception:`javax.crypto.BadPaddingException: Decryption error 
    at sun.security.rsa.RSAPadding.unpadV15(Unknown Source) 
    at sun.security.rsa.RSAPadding.unpad(Unknown Source) 
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363) 
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389) 
    at javax.crypto.Cipher.doFinal(Cipher.java:2165) 
    at model.EncriptionRSAKey.decryptAESKey(EncriptionRSAKey.java:54) 
    at test.EncriptionTest.testAESEncription(EncriptionTest.java:26) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)` 

感謝您的幫助

回答

1

這裏是你的錯誤:

privKey = keyGen.genKeyPair().getPrivate(); 
pubKey = keyGen.genKeyPair().getPublic(); 

每次調用keyGen.genKeyPair()生成新密鑰的時間。因此,privKey結束爲一個密鑰對的私鑰和pubkey最終作爲完全不相關的密鑰對的公鑰。相反,首先將KeyPair保存在變量中,例如

KeyPair keyPair = keyGen.genKeyPair(); 
privKey = keyPair.getPrivate(); 
pubKey = keyPair.getPublic(); 
+0

謝謝James :) – Andrea