我需要在客户端机器上对数据进行签名和加密。之后,我将使用 SFTP 将文件发送到服务器计算机。在服务器上,我想验证签名并解密数据。
这个方案安全吗?我应该怎么做才能提高安全性?
我正在执行以下步骤:
- 创建 Java 密钥库;
- 创建自签名 X509 v3 证书并将其插入 JKS 密钥库;
- 将此 JKS 密钥库提供给客户端和服务器;
- 签名数据:从 JKS 密钥库中获取私钥和证书,并使用
CMSSignedDataGenerator
and对数据进行签名CMSSignedData
; CMSEnvelopedDataGenerator
使用;加密上一步的有符号字节
在服务器端,我执行以下步骤:
- 加载 JKS;
- 从 JKS 检索私钥;
- 检索 CMSEnvelopedData 并获取 Content;
- 加载 X509 证书并使用 CMSSignedData 验证签名并恢复数据;
我只有一个公私钥对。我正在使用 Bouncy Castle 和 PKCS 7。
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;
}