数字签名示例

示例:
1,用keytool生成私钥和公钥证书
生成密钥库:
    keytool -genkey -alias privatekeystore -keystore private.keystore -storetype JKS -keyalg rsa -dname "CN=China ,OU=fan Unit, O=fan, L=shanghai, S=shanghai, C=China" -storepass 123456 -keypass 111111 -validity 3650
     注: keypass 是私钥的密码
导出公钥证书
    keytool -export -file testpublic.cer -keystore private.keystore -storepass 123456 -alias privatekeystore 
 打印证书
    keytool -printcert -file testpublic.cer


2,Send.java
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Signature;
import org.apache.log4j.Logger;

/**
 * 数字签名
 * <li>模拟发送方
 *  
 * @author hongwei.fan
 * @version $Id: Send.java, v 0.1 2011-12-25 下午04:11:07 hongwei.fan Exp $
 */
public class Send {
    private static final Logger logger = Logger.getLogger(Send.class);

    /**
     * 签名并且发送
     * 
     * @param fname
     * @param password
     * @param privateKeyAlias
     */
    public void signAndSend(String fname, char[] keystorePassword, String privateKeyAlias,
                            char[] privateKeyPwd) {
        try {
            FileOutputStream fos = new FileOutputStream("test");
            ObjectOutputStream oos = new ObjectOutputStream(fos);

            //获取keyStore
            KeyStoreHandler keyStoreHandler = new KeyStoreHandler(fname, keystorePassword);
            KeyStore keyStore = keyStoreHandler.getKeyStore();

            //从keyStore中获取私钥
            PrivateKey privateKey = (PrivateKey) keyStore.getKey(privateKeyAlias, privateKeyPwd);

            //私钥签名
            Signature signature = Signature.getInstance("MD5withRSA");
            signature.initSign(privateKey);
            String data = "Signature Data";
            signature.update(data.getBytes());

            //输出需要签名的数据和签名数据
            oos.writeObject(data);
            oos.writeObject(signature.sign());

        } catch (Exception e) {
            logger.warn("数字签名-发送方签名异常", e);
        }
    }
}


3,Receive.java
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.security.KeyStore;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import org.apache.log4j.Logger;

/**
 * 数字签名
 * <li>模拟接收方
 * 
 * @author hongwei.fan
 * @version $Id: Receive.java, v 0.1 2011-12-25 下午04:33:19 hongwei.fan Exp $
 */
public class Receive {
    private static final Logger logger = Logger.getLogger(Receive.class);

    /**
     * 接收并验签
     * @param keystoreFile
     * @param keystorePassword
     * @param publicKeyAlias
     */
    public void receiveAndVerify(String keystoreFile, char[] keystorePassword, String publicKeyAlias) {
        try {
            //读取输入流
            String data = null;
            byte[] signatureData = null;
            FileInputStream fis = new FileInputStream("test");
            ObjectInputStream ois = new ObjectInputStream(fis);
            Object object = ois.readObject();
            try {
                data = (String) object;
            } catch (ClassCastException cce) {
                logger.warn("读取源数据异常", cce);
            }

            object = ois.readObject();
            try {
                signatureData = (byte[]) object;
            } catch (ClassCastException cce) {
                logger.warn("读取签名数据异常", cce);
            }

            //获取公钥
            //方法1:从keyStore获取
            /*KeyStoreHandler ksh = new KeyStoreHandler(keystoreFile, keystorePassword);
            KeyStore keyStore = ksh.getKeyStore();
            Certificate cer = keyStore.getCertificate(publicKeyAlias);*/
            
            //方法2:从cer文件获取
            FileInputStream cerFile = new FileInputStream(this.getClass().getClassLoader()
                .getResource("key/testpublic.cer").toURI().getPath());
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            Certificate cer = cf.generateCertificate(cerFile);
            
            PublicKey publicKey = cer.getPublicKey();

            //公钥验签
            Signature signature = Signature.getInstance("MD5withRSA");
            signature.initVerify(publicKey);
            signature.update(data.getBytes());
            if (signature.verify(signatureData)) {
                logger.info("验签通过,data=" + data + ",signatureData=" + new String(signatureData));
            } else {
                logger.info("验签失败,data=" + data + ",signatureData=" + new String(signatureData));
            }

        } catch (Exception e) {
            logger.warn("接收方处理异常", e);
        }
    }
}


4,KeyStoreHandler.java
import java.io.FileInputStream;
import java.security.KeyStore;
import java.util.Enumeration;
import org.apache.log4j.Logger;

/**
 *  KeyStore 管理
 * @author hongwei.fan
 * @version $Id: KeyStoreHandler.java, v 0.1 2011-12-25 下午03:55:45 hongwei.fan Exp $
 */
public class KeyStoreHandler {
    private static final Logger logger = Logger.getLogger(KeyStoreHandler.class);
    private KeyStore            keyStore;

    /**
     * 构造函数
     * 加载keyStore文件
     * @param fname  keyStore 完整路径
     * @param password  keyStore 密码
     */
    public KeyStoreHandler(String fname, char[] password) {
        try {
            keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

            FileInputStream fis = new FileInputStream(fname);
            keyStore.load(fis, password);
            if (logger.isInfoEnabled()) {
                logger.info("密钥库中共有" + keyStore.size() + "个别名,分别是:");
            }
            Enumeration<String> aliases = keyStore.aliases();
            while (aliases.hasMoreElements()) {
                if (logger.isInfoEnabled()) {
                    logger.info((String) aliases.nextElement() + " ");
                }
            }
        } catch (Exception e) {
            logger.warn("密钥库操作异常", e);
            throw new IllegalArgumentException(e.toString());
        }
    }

    /**
     * 获取keyStore
     * @return
     */
    public KeyStore getKeyStore() {
        return keyStore;
    }
}


5,测试类
    public static void main(String[] args) throws Exception {
        String keystoreFile = "key/private.keystore";
        keystoreFile = Test.class.getClassLoader().getResource(keystoreFile).toURI().getPath();
        char[] keystorePassword = "123456".toCharArray();
        String privateKeyAlias = "privatekeystore";
        char[] privateKeyPwd = "111111".toCharArray();
        
        Send send = new Send();
        send.signAndSend(keystoreFile, keystorePassword, privateKeyAlias,privateKeyPwd);

        Receive receive = new Receive();
        receive.receiveAndVerify(keystoreFile, keystorePassword, privateKeyAlias);
    }

你可能感兴趣的:(数字签名)