一、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证书下载链接
1、生成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(); }
2、读取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(); }
3、通过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证书和数字签名技术,我们可以确保文件的完整性和来源,同时也可以避免文件在传输过程中被窃听或篡改,从而保证了数据的安全性和完整性。