PKCS12证书相关说明
一、PKCS12证书概述
PKCS12是基于密码学技术实现的一种证书格式,通常被用来存储私钥、公钥和证书信息。该证书格式主要由RSA Security和其它安全技术公司共同推广和开发。 PKCS12证书通常使用扩展名为“.pfx”或“.p12”,它可以包含多个证书链和私钥,同时也可以加密和保护存储在证书内的信息。在HTTPS协议中,服务器通常需要使用PKCS12证书来完成HTTPS协议的握手过程。在Java平台中,我们可以使用Keytool和OpenSSL等工具来生成和管理PKCS12证书。
二、PKCS12证书结构
一个PKCS12证书包含以下内容:
- 密码基元(Password-Based Encryption):这部分用于保护存储在证书中的所有信息,通常采用对称加密算法进行保护,比如AES、DES、RC2等算法。
- 私钥:该部分用于存储私钥信息,私钥通常存储在可移植证书中,以便于在不同设备之间进行转移。
- 证书链:证书链一般用于存储CA证书或者是其他需要的证书链,这些证书用于验证存储在PKCS12证书中的公钥与CA证书是否匹配。
- 证书属性(Attributes):PKCS12证书支持存储和管理一个特定的证书属性,比如证书过期时间、证书吊销等等。这些属性数据都是可选的,但它们可以帮助我们更好地管理和维护证书。
三、PKCS12证书下载链接
- 生成PKCS12证书的Java代码:
public static void createP12() throws Exception {
String alias = "12306";
String storePwd = "123456";
String exportPwd = "123456";
String keyPwd = "123456";
String certFilePath = "D:\\crt.crt";
String keyFilePath = "D:\\key.pem";
String keystoreFile = "D:\\test.p12";
Certificate cert = getCert(certFilePath); // reads certificate from file
PrivateKey privKey = getPrivateKey(keyFilePath, "RSA"); // reads private key from file
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(null, storePwd.toCharArray());
ks.setKeyEntry(alias, privKey, keyPwd.toCharArray(), new Certificate[] { cert });
FileOutputStream fos = new FileOutputStream(keystoreFile);
ks.store(fos, exportPwd.toCharArray());
fos.close();
}
- 读取PKCS12证书的Java代码:
public static void readP12() throws Exception {
String path = "D:\\test.p12";
String storePwd = "123456";
String alias = "12306";
String keyPwd = "123456";
String cerPath = "D:\\12306.cer";
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File(path));
keyStore.load(instream, storePwd.toCharArray());
instream.close();
Certificate[] certs = keyStore.getCertificateChain(alias); // returns the certificate chain
Certificate cert = keyStore.getCertificate(alias); // returns the certificate
Key key = keyStore.getKey(alias, keyPwd.toCharArray()); // returns the private key
byte[] encoded = key.getEncoded();
FileOutputStream fos = new FileOutputStream(cerPath);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate certificate = null;
for (Certificate c : certs) {
certificate = c;
fos.write(certificate.getEncoded());
}
fos.close();
}
- 通过OpenSSL生成PKCS12证书的命令行:
openssl pkcs12 -export -inkey my_key.pem -in my_cert.crt -out my_cert.pkcs12
四、PKCS12证书应用场景
PKCS12证书广泛地应用在安全通信、数字签名、认证等领域,以及在HTTPS协议中提供了一种安全的传输协议。在Java平台中,我们可以使用PKCS12证书来完成HTTPS协议的握手过程,也可以通过PKCS12证书来完成对文件或数据进行数字签名的操作。 例如,我们可以使用以下Java代码,来对文件进行数字签名:
public static void sign(String p12Path, String p12Pwd, String srcFilePath, String destFilePath) throws Exception {
String algorithm = "SHA1withRSA"; // the algorithm used for signing
File f = new File(srcFilePath);
FileInputStream fin = new FileInputStream(f);
byte[] buffer = new byte[(int) f.length()];
fin.read(buffer);
KeyStore ks = KeyStore.getInstance("PKCS12");
FileInputStream kins = new FileInputStream(p12Path);
char[] password = p12Pwd.toCharArray();
ks.load(kins, password);
String alias = ((java.security.KeyStore.PrivateKeyEntry) ks.getEntry(alias, new java.security.KeyStore.PasswordProtection(password))).getCertificate().toString();
PrivateKey privateKey = (PrivateKey) ks.getKey(alias, password);
Signature signature = Signature.getInstance(algorithm);
signature.initSign(privateKey, SecureRandom.getInstance("SHA1PRNG"));
signature.update(buffer);
byte[] signedBytes = signature.sign();
FileOutputStream fos = new FileOutputStream(destFilePath);
fos.write(signedBytes);
fos.close();
}
通过PKCS12证书和数字签名技术,我们可以确保文件的完整性和来源,同时也可以避免文件在传输过程中被窃听或篡改,从而保证了数据的安全性和完整性。