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:
- Creating a Java keystore;
- Creating self signed X509 v3 certificate and inserting it into the JKS keystore;
- Giving this JKS keystore to both client and server;
- Signing data : getting Private key and the certificate from the JKS keystore and signing data using
CMSSignedDataGenerator
andCMSSignedData
; - Encrypting the signed byte of previous step using
CMSEnvelopedDataGenerator
;
At the server side I perform the following steps:
- Loading the JKS;
- Retrieve the private key from JKS;
- Retrieve CMSEnvelopedData and get Content;
- 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;
}