2
votes

I want to use RSA/AES file encryption on my project. I make a pair of keys private/public with rsa, and one AES key, after that, i'll cipher AES key with public key. Finally i decrypt AES encrypted key with private RSA key.

This is the code: RSA key:

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

Test Class

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

on this line: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)`

Thanks for your help

1

1 Answers

1
votes

Here is your bug:

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

Each time you call keyGen.genKeyPair() a new keypair is generated. Thus privKey ends up as the private key of one keypair and pubkey ends up as the public key of a completely unrelated keypair. Instead, save the KeyPair in a variable first, e.g.

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