2

I'm not a crypto/security expert and have designed an architecture for encryption/decryption. I'm not sure if its full proof and want to know what people use as industry standard?

I'm trying to perform encryption/decryption in RESTful api where client sends encrypted payload and server decrypts it and does some processing. The server then sends encrypted response which the client decrypts and does some processing.

The architecture I've decided is:

  • One of the server periodically(once in 24hrs) generates a RSA keypair and uploads encrypted private key to redis so that other servers can get it and use decrypted private key from a master key.
  • create an api to share current active public key.

client:

  • get current active public key from server as raw text
  • generate new symmetric key
  • encrypt request with symmetric key
  • encrypt symmetric key with public key
  • encrypt iV with public key
  • send request

server:

  • decrypt iV with private key
  • decrypt symmetric key with private key
  • decrypt payload with symmetric key
  • encrypt response with symmetric
  • send response

client:

  • decrypt response with symmetric key

I'm using java.security and javax.crypto for all the key generation, cipher encryption/decryption.

The transformations I'll be doing is

  • RSA transformation RSA/ECB/OAEPWithSHA-256AndMGF1Padding
  • AES transformation AES/GCM/PKCS5Padding

Is this architecture okay to use? The reason for creating an api to get public key is so that we can do key rotation periodically. Also, I'll create an admin only api to force change the RSA key pair incase private key leak.

My major concern is the api that shares naked public key. Is this a valid approach and what are its problems? What are my options otherwise? Any help would be greatly appreciated because this is a very new topic for me and I am finding it very interesting!

Update

  • I'm using TLS/SSL for communication and want to add additional level of encryption
9
  • 1
    Why aren't you using TLS?
    – Marc
    Commented Sep 30, 2020 at 12:13
  • 2
    TLS already provides privacy, data integrity, and authentication (either one or both ways). Why isn't that sufficient? You don't need to re-encrypt data in transit that is already using TLS.
    – Marc
    Commented Sep 30, 2020 at 12:16
  • 2
    If TLS with good ciphers and key strengths is broken (all of which are configured by you), why would your custom encryption be any better?
    – Marc
    Commented Sep 30, 2020 at 12:22
  • 2
    You shouldn't be using a TLS-terminating proxy you don't control. Even if you do have one, it's recommended to terminate TLS at the backend.
    – Marc
    Commented Sep 30, 2020 at 12:29
  • 1
    "it passes through their own layer ..."? Really? You're going to have to back up that claim. If instead you want to argue that the OS can access your data, sure, it has access to all memory contents. Throwing more encryption wouldn't help. And this is getting away from OP's question.
    – Marc
    Commented Sep 30, 2020 at 12:36

1 Answer 1

1

As others have mentioned, you already have TLS, so this won't add any security, it'll just slow things down.

You mention sharing a private key between servers. Don't do that. Ever. Generate individual key pairs for every server, and have your central server sign them (the usual certificate generation process, with your central server as the CA).

The method you've proposed is otherwise OK but slow. Why not try libsodium boxes? Then it's a matter of calling crypto_box_easy() on the sender side, and crypto_box_open_easy() on the receiver side (obviously after key/nonce generation and exchange of public key from receiver to sender). There are bindings for Java.

8
  • But if I don't share the key pairs among servers, how will the client get the right public key? the load balancer will cycle through the servers and so the client will get a public key from one server and sent the request to a differnt server which has a different private key? Commented Sep 30, 2020 at 13:59
  • Also, i did ask about libsodium and java crypto on stackoverflow.com/questions/64121422/… Commented Sep 30, 2020 at 14:03
  • The load balancer won't interrupt an existing connection. Perform the exchange within a single connection. Commented Sep 30, 2020 at 16:58
  • 1
    As for why I recommend libsodium, it prevents mistakes (like using RSA encryption) that Java's built in crypto library makes easy. Commented Sep 30, 2020 at 16:59
  • 1
    You have a TLS (and thus TCP) connection straight from client to server. Not from client to load balancer. The same mechanism works for any layers you add over it. Just because it's RESTful doesn't mean there's no TCP session. Commented Oct 1, 2020 at 17:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .