0

I need to sign and encrypt data at client machine. After that I'll send the file to the server machine using SFTP. On the server I want to verify the signature and decrypt the data.

Is this scheme secure? What should I do to improve security ?

I'm executing the following steps:

  1. Creating a Java keystore;
  2. Creating self signed X509 v3 certificate and inserting it into the JKS keystore;
  3. Giving this JKS keystore to both client and server;
  4. Signing data : getting Private key and the certificate from the JKS keystore and signing data using CMSSignedDataGenerator and CMSSignedData;
  5. Encrypting the signed byte of previous step using CMSEnvelopedDataGenerator;

At the server side I perform the following steps:

  1. Loading the JKS;
  2. Retrieve the private key from JKS;
  3. Retrieve CMSEnvelopedData and get Content;
  4. Load the X509 certificate and validating signature using CMSSignedData and recovering back the data;

I have only one public-private key pair. I am using Bouncy Castle and PKCS 7.


Creation of JKS:

public static KeyStore createKeyStore() throws Exception {
         KeyStore keyStore = KeyStore.getInstance("JKS");
         keyStore.load(null, null);

    X500PrivateCredential rootCredential = createRootCredential();
    X500PrivateCredential interCredential = createIntermediateCredential(
            rootCredential.getPrivateKey(), rootCredential.getCertificate());
    X500PrivateCredential endCredential = createEndEntityCredential(
            interCredential.getPrivateKey(),
            interCredential.getCertificate());

    keyStore.setCertificateEntry(rootCredential.getAlias(),
            rootCredential.getCertificate());
    keyStore.setKeyEntry(
            endCredential.getAlias(),
            endCredential.getPrivateKey(),
            ConfigurationClass.PRIVATE_KEY_PASSWORD.toCharArray(),
            new Certificate[]{endCredential.getCertificate(),
                interCredential.getCertificate(),
                rootCredential.getCertificate()});

    keyStore.store(new FileOutputStream(ConfigurationClass.JAVA_KEY_STORE_PATH), ConfigurationClass.KEY_STORE_PASSWORD.toCharArray());
    return keyStore;
}
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
Arvind
  • 1,207
  • 6
  • 27
  • 55
  • Next time, at the minimum, re-read your question and remove spelling mistakes please. – Maarten Bodewes Aug 26 '12 at 00:41
  • Could anyone explain why I cannot indicate that this is Java code? I tried most of the options explained [here](http://meta.stackoverflow.com/editing-help#syntax-highlighting). – Maarten Bodewes Aug 26 '12 at 00:48

2 Answers2

2

Don't do this. Just transfer the data over SFTP but use certificates(issued by the server) for authentication. According to this post, this can be done with the JSch library.

If your encrypted the data right before sending it and then decrypting it right after, your doing transport security, not data at rest security.

Rolling your own crypto,even if you are assembling it out of good primitives, is bad and general fails. In the case of what you are doing you have at least two problems:

  1. You need to encrypt and then sign the encrypted data to prevent things like a Padding oracle attack
  2. Your key management could get problematic:

    1. How do you deal with new clients coming on ?
    2. What prevents an attacker from adding their key to the server ?

      This might seem like a stupid question, but really, if you have an outside service giving the server keys, how does the server authenticate that service? The correct way is to either have the server issue the keys signed under its (self-signed) "root" authority (this could also be some other trusted sever you have).

Community
  • 1
  • 1
imichaelmiers
  • 3,449
  • 2
  • 19
  • 25
  • 1
    Regarding your first point 1, I believe you should always sign **then** encrypt, right? http://world.std.com/~dtd/sign_encrypt/sign_encrypt7.html But that just proves your point even more - don't roll your own crypto. – Luke Aug 22 '12 at 15:32
  • @imichaelmiers What should be my key and certificate sharing mechanism the , am i doing wrong as for client cerificate is also generate by server ? any article which focus on real world scenario ? – Arvind Aug 23 '12 at 06:38
  • 1
    @Arvind Unless your worried about the server maliciously keeping the client's private key ( assuming the key is only used with the server, this is not a worry.) then yeah you can generate and sign a client cert on the server. If not you generate a Cerificate signing Request(CSR) and send it to the server. Depending on how sensitive your data is, you might want to use a third server(as your own CA) for generating and issuing certs. Then sftp server has the CA's cert and the client has the cert+private key signed by the CA. Thus if one of your SFTP servers is compromised, you're still ok. – imichaelmiers Aug 27 '12 at 22:28
1

What you are describing is certainly not secure. Private keys should not travel; key pairs are normally generated at the location where they are needed.

What you need to do is create some kind of infrastructure CA using a self signed certificate. You should keep the private key for this very safe (actually, as the private key is only needed to sign other certificates, you may literally store it in a safe).

Now you generate two key pairs and two certificate requests on both the client and on the server. Send both certificate requests to the infrastructure CA. This CA should sign the requests (and add data), generating the certificates. Certificates are send to the client and server, adding them to their own (password protected) JKS stores.

Now to transmit data you should encrypt with the public key of the server and then sign with the private key of the client. The server should first verify the signature of the client, then decrypt with it's own private key. If you don't you are succeptible to padding oracle attacks. For this it needs the CA certificate to verify the certificate chain.

Try and understand as much about PKI as possible before continuing. And remember that your scheme is only as safe as your private keys (and thus the JKS passwords). What I described is only the general structure, there are lots of implementation details.

Note: I've ignored the SFTP as you did not expand into that either. Strictly speaking, you shoud not need it.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Thanks a lot , can you please give me books or article or blog link where can i find directly point to point implementation of corporate level security and best practices for security – Arvind Aug 27 '12 at 05:33
  • No, I cannot as most of what I learned, is from practice. Most of the Java books that are out there on crypto are pretty good, but you might as well use a site with reviews for that. – Maarten Bodewes Aug 27 '12 at 07:20