数字签名示例
示例:
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
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); } }}
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); } }}
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; }}
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); }