SHA1即安全哈希算法(Secure Hash Algorithm),用于签名;RSA是目前最有影响力的公钥加密算法。 说到这就的提到公钥和私钥:公钥、私钥分居客户端和服务器端,分别用于加密和解密。同时,私钥还用于签名,公钥还用于验证签名。
下边是一个发送端的签名及对签名的加密,接收端的解密与验证签名的应用:
注释:SHA1WithRSA:用SHA算法进行签名,用RSA算法进行加密 发送端的签名及对签名的加密,接收端的解密与验证签名
// 1)使用私钥签名
public String signData(String param,String cafile)
{
InputStream inputStream = null ;
try
{
String store_password ="store_password";//密钥库密码
String password ="privateKey_password";//私钥密码
String keyAlias = "keyalias";//别名
//a. 创建针对jks文件的输入流
inputStream = new FileInputStream(cafile);//CA 文件名 如: D://tmp/encrypt.jks
// input = getClass().getClassLoader().getResourceAsStream(keyFile); 如果制定classpath下面的证书文件
//b. 创建KeyStore实例 (store_password密钥库密码)
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(inputStream,store_password.toCharArray());
//c. 获取私钥 (keyAlias 为私钥别名,password为私钥密码)
PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias,password.toCharArray());
// 实例化一个用SHA算法进行散列,用RSA算法进行加密的Signature.
Signature dsa = Signature.getInstance("SHA1withRSA");
// 加载加密散列码用的私钥
dsa.initSign(privateKey);
// 进行散列,对产生的散列码进行加密并返回
dsa.update(param.getBytes());
BASE64Encoder encoder = new BASE64Encoder();//加密后的也是二进制的,但是返回给调用方是字符串,本文就介绍了将byte[]转为各种进制以及base64编码
return encoder.encodeBuffer(dsa.sign());//进行签名
}
catch (Exception gse)
{
gse.getStackTrace();
return null;
}finally
{
try
{
if (inputStream != null)
inputStream.close();//判断
}
catch (Exception e)
{
e.getStackTrace();
}
}
}
/* 2) 用公钥证书对参数串进行签名验证
* @param cerfile 公钥文件路径
* @param urlParam 需要进行签名验证的参数
* @param signParam 编码后的签名
* @author lijunyu 20090120
* @return 校验签名,true为正确 false为错误
*/
public boolean verifyData(String cerfile ,String urlParam, String signParam)
{
boolean verifies = false;
//File file = new File(p7bFile);
// if(!file.exists()){//如果公钥不存在,就直接返回
// log.debug("keystore校验签名异常,公钥不存在! ");
// return verifies;
// }
InputStream in = null;
try
{
String store_password ="store_password";//密钥库密码
String password ="privateKey_password";//私钥密码
String keyAlias = "keyalias";//别名
//a. 创建针对jks文件的输入流
InputStream inputStream = new FileInputStream(cerfile);//CA 文件名 如: D://tmp/cerfile.p7b
// input = getClass().getClassLoader().getResourceAsStream(keyFile); 如果制定classpath下面的证书文件
//b. 创建KeyStore实例 (store_password密钥库密码)
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(inputStream,store_password.toCharArray());
//c. 获取公钥 (keyAlias 为公钥别名)
PublicKey pubKey= keyStore.getCertificate(keyAlias).getPublicKey();
/* 也可以通过CertificateFactory获得公钥,见后面的例子
CertificateFactory certificateFactory = CertificateFactory.getInstance(X509);//或者"X.509"
Certificate certificate = certificateFactory.generateCertificate(in);
publicKey = certificate.getPublicKey();*/
if (pubKey != null)
{
//d. 公钥进行验签
//获取Signature实例,指定签名算法(与之前一致)
Signature dsa = Signature.getInstance("SHA1withRSA");
//加载公钥
dsa.initVerify(pubKey);
//更新原数据
dsa.update(urlParam.getBytes());
BASE64Decoder decoder = new BASE64Decoder();
//公钥验签(true-验签通过;false-验签失败)
verifies = dsa.verify(decoder.decodeBuffer(signParam));//将签名数据从ase64编码字符串转回字节数组
}
}
catch (Exception gse)
{
gse.getStackTrace();
}
finally
{
try
{
if (in != null)
in.close();//判断
}
catch (Exception e)
{
e.getStackTrace();
}
}
return verifies;
}
可以从网上获取的工具类代码CertificateUtils.java,其中把生成的密钥库和证书都放到类的同包下,这个需要注意。
对应链接为http://blog.sina.com.cn/s/blog_8417657f0101fjlb.html