• 数字证书加密解密数据和数字签名


        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

     

  • 相关阅读:
    windows 配置免密登录 centos7
    早盘消息 2月16日 周三
    早报 3月1日 周二
    早报 2月23日 周三
    早报 3月4日 周五
    早报 2月21日 周一
    早盘消息 2月17日 周四
    早报 2月22日 周二
    如何在远程机器上运行多个 SSH 命令并安全退出
    早报 2月28日 周一
  • 原文地址:https://www.cnblogs.com/wen12128/p/2732209.html
Copyright © 2020-2023  润新知