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

    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

 

posted @ 2012-10-20 15:48  WenEric  阅读(687)  评论(0编辑  收藏  举报