数字证书加密解密数据和数字签名
Java6提供了完善的数字证书管理实现,我们几乎无需关注相关具体算法,仅通过操作密钥库和数字证书就可完成相应的加密/解密和签名/验证操作。密钥库管理私钥,数字证书管理公钥,私钥和密钥分属消息传递两方,进行加密消息传递。因此,我们可以将密钥库看做私钥相关操作的入口,数字证书则是公钥相关操作的入口。
首先用keytool生成密钥库:
View Code
验证是否已创建过同名的证书: keytool -list -v -alias testkeypair -keystore /home/testkeystore -storepass 123456 删除已创建的证书: keytool -delete -alias testkeypair -keystore /home/testkeystore -storepass 123456 创建证书: keytool -genkey -alias testkeypair -keyalg RSA -keystore /home/testkeystore -keysize 1024 -sigalg MD5withRSA -dname "CN=localhost, OU=dev, O=company, L=HZ, ST=ZJ, C=CH" -keypass 123456 -storepass 123456 -validity 30000 -v 产生自签证书: keytool -selfcert -alias cp2yzzckeypair -keystore /home/cp2ykeystore -dname "CN=211.155.230.138, OU=cp2y, O=binguo, L=HZ, ST=ZJ, C=CH" -storepass cp2y2012binguo 导出证书: keytool -export -rfc -alias testkeypair -keystore /home/testkeystore -file /home/test.cer -storepass 123456 客户端配置: keytool -import -trustcacerts -alias testkeypair -keystore /home/testkeystore -file /home/test.cer -storepass 123456 查看证书是否导入到JVM: keytool -list -alias testkeypair -keystore /home/testkeystore -storepass 123456 详细列出keystore中所有的密钥信息: keytool -keystore /home/testkeystore -storepass 123456 -list -v
密钥库包含私钥、公钥 还有其他信息等,获得私钥和公钥后,就可以进行加密解密了(非对称加密-可以私钥加密公钥解密,也可以公钥加密私钥解密)。当然,获得公钥私钥后,也可以使用私钥进行数字签名,然后用公钥来验证签名.
View Code
import java.io.FileInputStream; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import javax.crypto.Cipher; public class SHACoderTest { // 类型证书X509 public static final String CERT_TYPE = "X.509"; /** * 获得KeyStore * @param keyStorePath 密钥库路径 * @param password 密码 * @return KeyStore 密钥库 */ private static KeyStore getKeyStore(String keyStorePath, String password) throws Exception { // 实例化密钥库 KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); // 获得密钥库文件流 FileInputStream is = new FileInputStream(keyStorePath); // 加载密钥库 ks.load(is, password.toCharArray()); // 关闭密钥库文件流 is.close(); return ks; } /** * 由KeyStore获得私钥 * @param keyStorePath 密钥库路径 * @param alias 别名 * @param password 密码 * @return PrivateKey 私钥 * @throws Exception */ private static PrivateKey getPrivateKeyByKeyStore(String keyStorePath, String alias, String password) throws Exception { // 获得密钥库 KeyStore ks = getKeyStore(keyStorePath, password); // 获得私钥 return (PrivateKey) ks.getKey(alias, password.toCharArray()); } /** * 由Certificate获得公钥 * @param certificatePath证书路径 * @return PublicKey 公钥 * @throws Exception */ private static PublicKey getPublicKeyByCertificate(String certificatePath) throws Exception { // 获得证书 Certificate certificate = getCertificate(certificatePath); // 获得公钥 return certificate.getPublicKey(); } /** * 获得Certificate * @param certificatePath 证书路径 * @return Certificate 证书 * @throws Exception */ private static Certificate getCertificate(String certificatePath) throws Exception { // 实例化证书工厂 CertificateFactory certificateFactory = CertificateFactory .getInstance(CERT_TYPE); // 取得证书文件流 FileInputStream in = new FileInputStream(certificatePath); // 生成证书 Certificate certificate = certificateFactory.generateCertificate(in); // 关闭证书文件流 in.close(); return certificate; } /** * 获得Certificate * @param keyStorePath 密钥库路径 * @param alias 别名 * @param password 密码 * @return Certificate 证书 * @throws Exception */ private static Certificate getCertificate(String keyStorePath, String alias, String password) throws Exception { // 获得密钥库 KeyStore ks = getKeyStore(keyStorePath, password); // 获得证书 return ks.getCertificate(alias); } /*** * 私钥加密 * @param data 待加密数据 * @param keyStorePath 密钥库路径 * @param alias 别名 * @param password 密码 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String keyStorePath, String alias, String password) throws Exception { // 取得私钥 PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath, alias, password); // 对数据加密 Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 私钥解密 * @param data 待解密数据 * @param keyStorePath 密钥库路径 * @param alias 别名 * @param password 密码 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] data, String keyStorePath, String alias, String password) throws Exception { // 取得私钥 PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath, alias, password); // 对数据加密 Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 公钥加密 * @param data 待加密数据 * @param certificatePath 证书路径 * @return byte[] 加密数据 * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, String certificatePath) throws Exception { // 取得公钥 PublicKey publicKey = getPublicKeyByCertificate(certificatePath); // 对数据加密 Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 公钥解密 * @param data 待解密数据 * @param certificatePath 证书路径 * @return byte[] 解密数据 * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data, String certificatePath) throws Exception { // 取得公钥 PublicKey publicKey = getPublicKeyByCertificate(certificatePath); // 对数据加密 Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 签名 * @param keyStorePath 密钥库路径 * @param alias 别名 * @param password 密码 * @return byte[] 签名 * @throws Exception */ public static byte[] sign(byte[] sign, String keyStorePath, String alias, String password) throws Exception { // 获得证书 X509Certificate x509Certificate = (X509Certificate) getCertificate( keyStorePath, alias, password); // 构建签名,由证书指定签名算法 Signature signature = Signature.getInstance(x509Certificate .getSigAlgName()); // 获取私钥 PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath, alias, password); // 初始化签名,由私钥构建 signature.initSign(privateKey); signature.update(sign); return signature.sign(); } /** * 验证签名 * @param data 数据 * @param sign 签名 * @param certificatePath 证书路径 * @return boolean 验证通过为真 * @throws Exception * */ public static boolean verify(byte[] data, byte[] sign, String certificatePath) throws Exception { // 获得证书 X509Certificate x509Certificate = (X509Certificate) getCertificate(certificatePath); // 由证书构建签名 Signature signature = Signature.getInstance(x509Certificate .getSigAlgName()); // 由证书初始化签名,实际上是使用了证书中的公钥 signature.initVerify(x509Certificate); signature.update(data); return signature.verify(sign); } }
参考:http://zhuyuehua.iteye.com/blog/1104305