示例:
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);
}