下边是一个使用数字证书来进行数字签名(以及验证签名信息),以及非对称加密的一个demo,代码中使用PKCS12类型的keystore(包含私钥)使用JKS或者其他类型的keystore也是可以的,就是在加载keystore的时候有一些不同
关于公钥,私钥和数字签名的一个比较容易的理解可以参考这篇文章:http://blog.csdn.net/21aspnet/article/details/7249401
PKCS12 证书的生成及验证
https://blog.csdn.net/kmyhy/article/details/6431609
package com.jiaoyiping.passwordmanager.pki;
/*
* Created with Intellij IDEA
* USER: 焦一平
* Mail: jiaoyiping@gmail.com
* Date: 2016/10/2
* Time: 12:05
* To change this template use File | Settings | Editor | File and Code Templates
*/
import org.apache.commons.codec.binary.Hex;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
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.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
/**
* 签名和验证签名
*/
public class TestSign {
//证书密码
private static final String PASSWORD = "123456";
//证书别名
private static final String ALIAS = "test";
public static void main(String[] args) throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("D:\\test.p12"), PASSWORD.toCharArray());
Certificate x509Certificate = keyStore.getCertificate(ALIAS);
encrypt(x509Certificate.getPublicKey(), (PrivateKey) keyStore.getKey(ALIAS, PASSWORD.toCharArray()));
System.out.println("==============================================================================");
sign(keyStore);
}
/**
* 签名和验证签名
*
* @throws Exception
*/
public static void sign(KeyStore keyStore) throws Exception {
X509Certificate x509Certificate = (X509Certificate) keyStore.getCertificate(ALIAS);
//需要签名的信息的内容
String message = "中国移动通信研究院";
//获取CA证书私钥
PrivateKey priKey = (PrivateKey) keyStore.getKey(ALIAS, PASSWORD.toCharArray());
System.out.println("私钥:" + Hex.encodeHexString(priKey.getEncoded()));
//用私钥签名
Signature signature = Signature.getInstance("NONEwithRSA");
signature.initSign(priKey);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
dataOutputStream.writeUTF(message);
signature.update(byteArrayOutputStream.toByteArray());
String result = Hex.encodeHexString(signature.sign());
System.out.println("签名之后的内容:" + result);
//用公钥来验证签名
Signature signature1 = Signature.getInstance("NONEwithRSA");
signature1.initVerify(x509Certificate.getPublicKey());
System.out.println("公钥:" + Hex.encodeHexString(x509Certificate.getPublicKey().getEncoded()));
ByteArrayOutputStream byteArrayOutputStream1 = new ByteArrayOutputStream();
DataOutputStream dataOutputStream1 = new DataOutputStream(byteArrayOutputStream1);
dataOutputStream1.writeUTF(message);
signature1.update(byteArrayOutputStream1.toByteArray());
System.out.println("验证结果: " + signature1.verify(Hex.decodeHex(result.toCharArray())));
}
/**
* 加密和解密
*
* @param publicKey
* @param privateKey
* @throws Exception
*/
public static void encrypt(PublicKey publicKey, PrivateKey privateKey) throws Exception {
String input = "慧与(中国)有限公司";
Cipher cipher = Cipher.getInstance("RSA");
RSAPublicKey pubKey = (RSAPublicKey) publicKey;
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] cipherText = cipher.doFinal(input.getBytes());
//加密后的内容
System.out.println("加密之后的内容:" + Hex.encodeHexString(cipherText));
//解密
cipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey);
byte[] plainText = cipher.doFinal(cipherText);
System.out.println("解密之后的内容 : " + new String(plainText));
}
}
运行结果
来源:https://blog.csdn.net/weixin_37569048/article/details/80038206