Which of the encryption aproaches should I use?

| | August 7, 2015

I need a system to exchange very secret data (source code that is a trade secret). I will use Crypto++ so practically I can use all encryption algorithms, although I really prefer to use an industry standard.

Currently I’m thinking on these methods:

  1. Have the server generate 2048/4096-bit RSA keys, send the public key over to the client, have the client encrypt the data then send it over to the server.
  2. Use a key exchange method like Diffie-Hellman (Diffie-Hellman-Merkle to be correct) to exchange an AES-256 key.
  3. Initiate a TLS connection and tell the server the AES key directly.

Which approach do you believe I should use? I’m not concerned about performance as long as it’s reasonable; security is what matters. If none of them, please suggest another method.

P.S.: I might use chaining on the symmetric algorithm, like AES-Twofish-Serpent.

EDIT: Any recommended software must be in a license that won’t restrict proprietary usage. LGPL is as restrictive as it must get. That rules out GPL.

3 Responses to “Which of the encryption aproaches should I use?”

  1. Don’t develop your own key exchange and/or key provisioning protocol(s). This is what historically breaks most products and, unless you are a cryoptographer (not a programmer with crypto experience), you’ll likely get it wrong.

    Use off-the-shelf protocols like SSL/TLS. Eg. TLS initialized with RSA keypairs for mutual authentication and AES session keys sounds appropiate for what you describe


    Bruce Schneier:

    “A colleague once told me that the world was full of bad security
    systems designed by people who read
    Applied Cryptography”

    erickson in his post has already give you plenty of evidence why designing your own key provisioning and management protocol is flawed. I just want to drive the point home why Mallory is alive and doing quite well, thanks to overconfident developers:

    You design the scheme you propose where the client encrypts with a public key and sends the document back to you. Things work great, but 1 year down the road the certificate is approaching expiration. You send an email out to your clients with the new certificate containing the public key you want your users to sign encrypts the documents with for you. Unknown to you is that over the past 4 months your ISP admin has received a bribe to route all your IP traffic through a remote machine. Your email is intercepted before distribution and your attached certificate is replaced with another one. All your clients are now sending their ultra secret documents encryted for someone else’s private key. An application decrypts each one, stores it, then encrypts it with your public key and forwards the traffic to you. You won’t even know is happening, untill by accident during a visit to a client’s site you notice that the certificate he uses is not the one you distributed.

    You mention in your post as an option to chain algorithms. Nobody is going to brute force you. Your weakness will be key management, and the attack will take some form of social engineering to fool someone is using the wrong key, or reveling the private key (again, bribes go a long way). Industry agreed protocols have steps to prevent man-in-the-middle attacks, they may rely on PKI infrastructure that recognizes designated key use and trusted authorities, they add certificate revocation list check steps to the validation etc etc. Just ‘I encrypt with public key, you decrypt with private’ does not make a secret safe.

  2. I’d recommend using an existing S/MIME (or CMS) implementation with a solid cryptographic module to encrypt your content.

    S/MIME enveloped data makes a nice format for storage of encrypted data “at rest”: the envelope records information about the algorithms and keys used so that the information will be available to authorized recipients later, when it is needed.

    Also, even if it doesn’t support the “best” algorithms (like ECDH key agreement), a good library is much less likely to have vulnerabilities than something written by a general programmer. Since it is far, far more likely that security will be breached by an implementation error than cryptanalysis, it makes sense to minimize those errors.

    In legitimate protocols, public keys are signed by one of a small number of trusted issuers, whose public keys are distributed by some secure means “out-of-band”. If you already have a secure means to get a public key to the message sender, why bother sending another? And if you don’t, you’re screwed.

    TLS and S/MIME depend on having a set of well known CA certificates at every client. These are used to sign the server’s public key so that a client can detect attempts to substitute keys. The protocol can’t bootstrap itself; there must be a secure way to distribute “trust anchors” out-of-band.

    Also note that RSA is incredibly slow compared to symmetric ciphers. Real protocols generate a “content encryption key” for a symmetric algorithm like AES, then use an RSA public key as a “key encryption key” to encrypt the content encryption key for the message recipient(s).

    So, the main problem is getting your public key to the client securely. If you can do that, either option #1 or #2 is good—assuming that you just use that public key, rather than trying to send another one “in-band”. In fact, in CMS, Option #1 is called “key transport”, and Option #2 is called “key agreement”.

    In practice, the “server” could use a certificate issued by a CA that is already well known, or the client can compare a hash of the certificate with one that you tell him over the phone, or carve into the face of a cliff, or whatever. The critical thing is, all of your security depends on the integrity of the certificate. You have to protect it from tampering.

    While Crypto++ is an “industry standard”, its security depends on how you use it. Just like Jerry told Kramer, “the door must be… closed!” Using the cryptographic primitives in Crypto++ with in a poorly designed protocol will get you nowhere. That’s why I’m stressing the use of CMS (a higher-level protocol) together with a good cryptographic module (cryptographic primitives).

  3. Nicolas Viennot on November 30, -0001 @ 12:00 AM

    What about ssh ? (rsync on ssh for example) ?

Leave a Reply