Search code examples
javaencryptioncryptographyencryption-asymmetrictruststore

Java - asymmetric encryption of traffic with pre-shared public keys and without trust store hassles


I'm trying to communicate using RSA preshared keys and, ideally, without involving truststore shenanigans

The setup is basically like this:

There's an applet on client side and a servlet on server side (duh :) )

The applet has servlet's RSA public key (Spub) hardcoded.

The servlet has it's own RSA private key (Spriv) hardcoded.

They applet generates a random AES 256 key (session key), encrypts it with servlet's public key (which it has hardcoded), connects to the servlet over a TCP socket and sends the RSA-encrypted key to the servlet, which proceeds to decrypt the session key and use it for any further communication with this applet as long as this socket connection lasts.

I would rather do this all without messing with truststore and such (after all, it's a relatively straightforward setup which allows for a pre-shared hardcoded public key)

Any suggestions in regards to where I should start looking to educate myself ?


Solution

  • I would agree with the comments that SSL is a decent way to go, but to answer your direct question, the scheme you described is fairly simple and doesn't appear to give away any secrets. Here's an implementation of the RSA portion of the client, based on a hard-coded public key.

    // Hardcoded values extracted from getModulus of a generated KeySpec.
    private static BigInteger mod = new BigInteger("113...");
    private static BigInteger exp = new BigInteger("217...");
    
    private PublicKey hardCodedKey() {
        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(mod, exp);
        KeyFactory keyFactory = null;
        PublicKey rsaKey = null;
        try {
            keyFactory = KeyFactory.getInstance("RSA");
            rsaKey = keyFactory.generatePublic(keySpec);
        } catch (Exception ex) {
            throw new IllegalStateException(ex);
        }
        return rsaKey;
    }
    
    private byte[] encrypt(PublicKey pubKey, byte[] plaintext) {
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            return cipher.doFinal(plaintext);
        } catch (Exception ex) {
            throw new IllegalStateException(ex);
        }
    }