How to encrypt serializable objects

2019-08-17 02:27发布

I'm currently working on a client-server application in Java. Due to the requirements for the application I need to encrypt the traffic between client and server and decided to use a hybrid encryption approach where the server generates a public/private RSA key pair and the client generates an AES session key which will be encrypted using the RSA public key.

As I'm completely new to encryption in Java I didn't start implementing it directly into my application so I don't crash anything. I set up a test project to get a bit more familiar with how things work to get a better understanding of everything before applying it to the actual application.

I followed some tutorials where I generate a SecretKey to encrypt and decrypt the message which also works as expected. However I don't want to have one key that can be used for both, encryption and decryption, but rather have a PrivateKey and a PublicKey which I'm able to generate using KeyPairGenerator.

The problem is that when I do exactly the same things using the PrivateKey and the PublicKey I get a NullPointerException where it says "No installed provider supports this key: (null)". When trying to find some information on that problem I only found solutions that use a single SecretKey but that works for me as already mentioned.

As I haven't done anything before with encryption in Java I'm quite lost on what I need to do now or how to solve this as I find it hard to find a solution that deals with a key pair. For some more details, here is the code I used:

@SuppressWarnings("deprecation")
public class EncryptionTest {

    private SecretKey secretKey;
    private PrivateKey privKey;
    private PublicKey pubKey;

    public static void main(String[] args) {
        EncryptionTest test = new EncryptionTest();

        String s = "Hello";
        byte[] keyBytes = new byte[32];
        byte[] message = new byte[20];
        s.getBytes(0, s.length(), message, 0);
        message = test.encryptKeyPair(message, keyBytes);

        for (int i = 0; i < message.length; i++) {
            System.out.print(message[i]);
        }
        System.out.println("");
        message = test.decryptKeyPair(message, keyBytes);

        char originalChar;
        for (int i = 0; i < message.length; i++) {
            originalChar = (char) message[i];
            System.out.print(originalChar);
        }
    }

    public EncryptionTest() {
        try {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("AES", "SUN");
            SecureRandom random = SecureRandom.getInstanceStrong();
            keyGen.initialize(128, random);
            KeyPair pair = keyGen.generateKeyPair();
            privKey = pair.getPrivate();
            pubKey = pair.getPublic();
        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
        }
    }

    public byte[] encryptMessage(byte[] message, byte[] keyBytes) {

        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            secretKey = new SecretKeySpec(keyBytes, "AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            return cipher.doFinal(message);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }

        return null;
    }

    public byte[] decryptMessage(byte[] message, byte[] keyBytes) {

        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            return cipher.doFinal(message);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }

        return null;
    }

    public byte[] encryptKeyPair(byte[] message, byte[] keyBytes) {

        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, privKey);
            return cipher.doFinal(message);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }

        return null;
    }

    public byte[] decryptKeyPair(byte[] message, byte[] keyBytes) {

        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, pubKey);
            return cipher.doFinal(message);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }

        return null;
    }
}

The methods encryptMessage() and decryptMessage() are the methods that work as I only use a single secretKey and the methods encryptKeyPair() and decryptKeyPair() are the methods for encrypting and decrypting using the public / private key and the don't work for me.

Any help would be really apprectiated.

0条回答
登录 后发表回答