MD5及公私钥数据加密工具类
程序员文章站
2024-03-19 09:20:28
...
加签验签代码如下:
package com.allinpay.ets.pswd.util;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* 数据加密工具类
*
*
* @date 20180130
*
*/
public class SecurityUtils {
/**
* 执行初始化操作,将 BouncyCastleProvider添加到java.security.Security中
*/
/*
* static { Secu rity.addProvider(new BouncyCastleProvider()); }
*/
private SecurityUtils() {
}
/**
* 对数据做MD5摘要
*
* @param aData
* @return
* @throws SecurityException
*/
public static String MD5Encode(String aData) throws Exception {
String resultString = null;
MessageDigest md = MessageDigest.getInstance("MD5");
resultString = bytes2HexString(md.digest(aData.getBytes("UTF-8")));
return resultString;
}
public static String bytes2HexString(byte[] b) {
String ret = "";
for (int i = 0; i < b.length; i++) {
String hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
ret += hex.toUpperCase();
}
return ret;
}
/**
* 获得公钥
*
* @param modulus
* @param publicExponent
* @return
* @throws Exception
*/
public static PublicKey getPublicKey(String modulus, String publicExponent)
throws Exception {
BigInteger m = new BigInteger(modulus, 16);
BigInteger e = new BigInteger(publicExponent, 16);
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory keyFactory = KeyFactory.getInstance("RSA",
new BouncyCastleProvider());
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
/**
* 从modulus和exponent生成rsa的私钥,要求两个参数都是16进制格式
*
* @param modulus
* 16进制
* @param privateExponent
* 16进制
* @return
* @throws Exception
*
*/
public static PrivateKey getPrivateKey(String modulus,
String privateExponent) throws Exception {
BigInteger m = new BigInteger(modulus, 16);
BigInteger e = new BigInteger(privateExponent, 16);
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e);
KeyFactory keyFactory = KeyFactory.getInstance("RSA",
new BouncyCastleProvider());
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
/**
* 根据alias别名从store文件获得私钥信息
*
* @param storePath
* store文件地址
* @param alias
* 别名
* @param storePass
* store访问明码
* @param storeType
* store类型 为空时为默认值
* @return 私钥
* @throws Exception
*/
@Deprecated
public static PrivateKey getPrivateKeyFromStore(String storePath,
String alias, String storePass, String storeType) throws Exception {
// KeyTool中生成KeyStore时设置的alias
// alias = "paymentSign";
// KeyTool中生成KeyStore时设置的storetype
// storeType = "JCEKS";
// KeyTool中生成KeyStore时设置的storepass
char[] pw = storePass.toCharArray();
// KeyTool中已生成的KeyStore文件
// storePath = "C:/app/payment.keystore";
storeType = "JCEKS";
storeType = null == storeType ? KeyStore.getDefaultType() : storeType;
KeyStore keyStore = KeyStore.getInstance(storeType);
InputStream is = new FileInputStream(storePath);
keyStore.load(is, pw);
// 返回私钥
return (PrivateKey) keyStore.getKey(alias, pw);
}
/**
* 从keyStore中获取私钥
* @param storePath
* @param alias
* @param storePass
* @param storeType
* @return
* @throws Exception
*/
public static PrivateKey getPriKeyFromStore(String storePath,
String alias, String storePass, String storeType) throws Exception {
char[] pw = storePass.toCharArray();
if(StringUtils.isEmpty(storeType))
{
storeType = KeyStore.getDefaultType();
}
//获得KeyStore对象
KeyStore keyStore = KeyStore.getInstance(storeType,new BouncyCastleProvider());
//加载KeyStore库
InputStream is = new FileInputStream(storePath);
keyStore.load(is, pw);
// 返回私钥
return (PrivateKey) keyStore.getKey(alias, pw);
}
/**
* 从keyStore中获取私钥
* @param storePath
* @param alias
* @param storePass
* @param storeType
* @return
* @throws Exception
*/
public static PublicKey getPubKeyFromStore(String storePath,
String alias, String storePass, String storeType) throws Exception {
char[] pw = storePass.toCharArray();
if(StringUtils.isEmpty(storeType))
{
storeType = KeyStore.getDefaultType();
}
//获得KeyStore对象
KeyStore keyStore = KeyStore.getInstance(storeType);
//加载KeyStore库
InputStream is = new FileInputStream(storePath);
keyStore.load(is, pw);
// 返回公钥
return keyStore.getCertificate(alias).getPublicKey();
}
/**
* 从keyStore中获取证书Id
* @param storePath
* @param alias
* @param storePass
* @param storeType
* @return
* @throws Exception
*/
public static String getCertIdFromStore(String storePath,
String alias, String storePass, String storeType) throws Exception {
char[] pw = storePass.toCharArray();
if(null == storeType)
{
storeType = KeyStore.getDefaultType();
}
//获得KeyStore对象
KeyStore keyStore = KeyStore.getInstance(storeType,new BouncyCastleProvider());
//加载KeyStore库
InputStream is = new FileInputStream(storePath);
keyStore.load(is, pw);
// 返回证书
X509Certificate cert = (X509Certificate) keyStore
.getCertificate(alias);
return cert.getSerialNumber().toString();
}
/**
* 从keyStore中获取证书Encode
* @param storePath
* @param alias
* @param storePass
* @param storeType
* @return
* @throws Exception
*/
public static byte[] getEncodeFromStore(String storePath,
String alias, String storePass, String storeType) throws Exception {
char[] pw = storePass.toCharArray();
if(null == storeType)
{
storeType = KeyStore.getDefaultType();
}
//获得KeyStore对象
KeyStore keyStore = KeyStore.getInstance(storeType,new BouncyCastleProvider());
//加载KeyStore库
InputStream is = new FileInputStream(storePath);
keyStore.load(is, pw);
// 返回证书
X509Certificate cert = (X509Certificate) keyStore
.getCertificate(alias);
return cert.getEncoded();
}
/**
* 用私钥对数据签名,签名算法: SHA1withRSA
*
* @param src
* 明文数据
* @param privateKey
* 私钥对象 可直接使用
* @return 加密后密文
* @throws SecurityException
*/
public static String signByRSAwithSHA1(String src, PrivateKey priKey)
throws NoSuchAlgorithmException, InvalidKeyException,
SignatureException, SecurityException {
Security.addProvider(new BouncyCastleProvider());
Signature sigEng = Signature.getInstance("SHA1withRSA");
sigEng.initSign(priKey);
sigEng.update(src.getBytes());
byte[] signature = sigEng.sign();
String signMsg = CodeUtil.bytes2HexString(signature);
return signMsg;
}
/**
* 公钥验证
*
* @param pubKey
* @param srcBytes
* @param signBytes
* @param signAlg
* @return
*/
public static boolean verifyByPubKey(Key pubKey, byte[] srcBytes,
byte[] signBytes, String signAlg) {
boolean result = false;
try {
Signature sign = Signature.getInstance(signAlg,
new BouncyCastleProvider());
sign.initVerify((PublicKey) pubKey);
sign.update(srcBytes);
result = sign.verify(signBytes);
} catch (NoSuchAlgorithmException e) {
// LoggerUtil.error("公钥验签 - 无效算法:");
} catch (InvalidKeyException e) {
// LoggerUtil.error("公钥验签 - 无效的**:");
} catch (SignatureException e) {
// LoggerUtil.error("公钥验签 - 签名异常:");
}
return result;
}
/**
* 加签
*
* @param priKey
* @param srcBytes
* @param signAlg
* @return
*/
public static byte[] signByPriKey(Key priKey, byte[] srcBytes,
String signAlg) {
// 签名
byte[] signBytes = null;
try {
Signature sign = Signature.getInstance(signAlg,
new BouncyCastleProvider());
sign.initSign((PrivateKey) priKey);
sign.update(srcBytes);
signBytes = sign.sign();
} catch (NoSuchAlgorithmException e) {
// LoggerUtil.error("私钥签名 - 无效算法:");
} catch (InvalidKeyException e) {
// LoggerUtil.error("私钥签名 - 无效的**:");
} catch (SignatureException e) {
// LoggerUtil.error("私钥签名 - 签名异常:");
}
return signBytes;
}
/**
* 加签(Xml)
* Xml内部生成Signature标签
*
* @param priKey
* @param srcBytes
* @param signAlg
* @return
* @throws Exception
*/
public static byte[] signXmlByPriKey(Key priKey, byte[] srcBytes) throws Exception {
// 签名
byte[] signBytes = null;
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(
new ByteArrayInputStream(srcBytes));
XMLSignatureFactory factory = XMLSignatureFactory
.getInstance("DOM");
Transform envelopedTransform = factory.newTransform(
Transform.ENVELOPED, (TransformParameterSpec) null);
DigestMethod digestMethod = factory.newDigestMethod(
DigestMethod.SHA1, null);
CanonicalizationMethod canonicalizationMethod = factory
.newCanonicalizationMethod(
CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null);
SignatureMethod signatureMethod = factory.newSignatureMethod(
SignatureMethod.RSA_SHA1, null);
Reference ref = factory.newReference("", digestMethod, Collections
.singletonList(envelopedTransform), null, null);
SignedInfo si = factory.newSignedInfo(canonicalizationMethod,
signatureMethod, Collections.singletonList(ref));
XMLSignature signature = factory.newXMLSignature(si, null);
DOMSignContext domSignContext = new DOMSignContext(priKey, doc
.getDocumentElement());
signature.sign(domSignContext);
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer
.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
StreamResult streamResult = new StreamResult(outputStream);
transformer.transform(new DOMSource(doc), streamResult);
signBytes = outputStream.toByteArray();
}
catch (Exception e) {
throw e;
}
return signBytes;
}
/**
* 使用公钥,对传入的XML进行校验,如果校验成功,返回true,否则,返回false。
* 在校验的过程中,会将XML原文加载为DOM对象,在DOM中优先寻找签名元素,如果没有找到或者数量不止1个,则直接返回false。
*
* @param inputBytes
* XML报文的bytes
* @param pubKey
* 公钥对象
* @return 校验结果,成功:true,失败:false
* @throws Exception
*/
public static boolean verifyXmlByPubKey(byte[] inputBytes, PublicKey pubKey)
throws Exception {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
InputStream inputStream = new ByteArrayInputStream(inputBytes);
Document document = dbf.newDocumentBuilder().parse(inputStream);
/*
* 从XML原文中,找到签名报文元素。
* 如果找不到该节点,或者该节点的数量不为1,直接返回false。
*/
Node signatureNode = null;
NodeList childNodes = document.getElementsByTagNameNS(XMLSignature.XMLNS,"Signature");
if (childNodes.getLength() == 1) {
signatureNode = childNodes.item(0);
} else if (childNodes.getLength() == 0) {
return false;
} else {
return false;
}
DOMValidateContext valContext = new DOMValidateContext(pubKey,
signatureNode);
XMLSignatureFactory factory = XMLSignatureFactory
.getInstance("DOM");
XMLSignature signature = factory.unmarshalXMLSignature(valContext);
if (!signature.validate(valContext)) {
return false;
} else {
return true;
}
} catch (Exception e) {
throw e;
}
}
/**
* 私钥解密过程
*
* @param privateKey
* 私钥
* @param cipherData
* 密文数据
* @return 明文
* @throws Exception
* 解密过程中的异常信息
*/
public static byte[] decryptByPriKey(PrivateKey privateKey,
byte[] cipherData) throws Exception {
byte[] output = null;
if (privateKey == null) {
throw new Exception("解密私钥为空, 请设置");
}
Cipher cipher = null;
try {
// 使用默认RSA
cipher = Cipher.getInstance("RSA");
// cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
output = cipher.doFinal(cipherData);
} catch (NoSuchAlgorithmException e) {
// throw new Exception("无此解密算法");
} catch (NoSuchPaddingException e) {
// e.printStackTrace();
// return null;
} catch (InvalidKeyException e) {
// throw new Exception("解密私钥非法,请检查");
} catch (IllegalBlockSizeException e) {
// throw new Exception("密文长度非法");
} catch (BadPaddingException e) {
// throw new Exception("密文数据已损坏");
}
return output;
}
/**
* 私钥解密过程
*
* @param privateKey
* 私钥
* @param cipherData
* 密文数据
* @return 明文
* @throws Exception
* 解密过程中的异常信息
*/
public static byte[] encryptByPubKey(PublicKey publicKey,
byte[] cipherData) throws Exception {
byte[] output = null;
if (publicKey == null) {
throw new Exception("加密公钥为空, 请设置");
}
Cipher cipher = null;
try {
// 使用默认RSA
cipher = Cipher.getInstance("RSA");
// cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
output = cipher.doFinal(cipherData);
} catch (NoSuchAlgorithmException e) {
// throw new Exception("无此解密算法");
} catch (NoSuchPaddingException e) {
// e.printStackTrace();
// return null;
} catch (InvalidKeyException e) {
// throw new Exception("解密私钥非法,请检查");
} catch (IllegalBlockSizeException e) {
throw new Exception("密文长度非法");
} catch (BadPaddingException e) {
// throw new Exception("密文数据已损坏");
}
return output;
}
/**
* 从文件中输入流中加载公钥
* @param in 公钥输入流
* @throws Exception 加载公钥时产生的异常
*/
public static PublicKey loadPublicKey(InputStream in) throws Exception{
try {
BufferedReader br= new BufferedReader(new InputStreamReader(in));
String readLine= null;
StringBuilder sb= new StringBuilder();
while((readLine= br.readLine())!=null){
if(readLine.charAt(0)=='-'){
continue;
}else{
sb.append(readLine);
sb.append('\r');
}
}
return loadPublicKey(sb.toString());
} catch (IOException e) {
throw new Exception("公钥数据流读取错误");
} catch (NullPointerException e) {
throw new Exception("公钥输入流为空");
} catch (Exception e) {
throw e;
}
}
/**
* 从文件中加载私钥
* @param in 私钥输入流
* @param pkcs PKCS标准
* @return 是否成功
* @throws Exception
*/
public static PrivateKey loadPrivateKey(InputStream in,String pkcs) throws Exception{
try {
BufferedReader br= new BufferedReader(new InputStreamReader(in));
String readLine= null;
StringBuilder sb= new StringBuilder();
while((readLine= br.readLine())!=null){
if(readLine.charAt(0)=='-'){
continue;
}else{
sb.append(readLine);
sb.append('\r');
}
}
if("PKCS1".equals(pkcs)){
return loadPrivateKeyWithPcks1(sb.toString());
}else if("PKCS8".equals(pkcs)){
return loadPrivateKeyWithPcks8(sb.toString());
}else{
return loadPrivateKeyWithPcks1(sb.toString()); //默认
}
} catch (IOException e) {
throw new Exception("私钥数据读取错误");
} catch (NullPointerException e) {
throw new Exception("私钥输入流为空");
} catch (Exception e) {
throw e;
}
}
/**
* 载入私钥 PKCS8
* @param privateKeyStr
* @return
* @throws Exception
*/
public static PrivateKey loadPrivateKeyWithPcks8(String privateKeyStr) throws Exception{
try {
byte[] buffer= Base64.decode(privateKeyStr);
PKCS8EncodedKeySpec keySpec= new PKCS8EncodedKeySpec(buffer);
KeyFactory keyFactory= KeyFactory.getInstance("RSA");
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException e) {
throw new Exception("无此算法");
} catch (NullPointerException e) {
throw new Exception("私钥数据为空");
} catch (Exception e) {
throw e;
}
}
/**
* 载入私钥 PKCS1
* @param privateKeyStr
* @return
* @throws Exception
*/
public static RSAPrivateKey loadPrivateKeyWithPcks1(String privateKeyStr) throws Exception{
try {
byte[] buffer= Base64.decode(privateKeyStr);
RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence)ASN1Sequence.fromByteArray(buffer));
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent());
KeyFactory keyFactory= KeyFactory.getInstance("RSA");
return (RSAPrivateKey)keyFactory.generatePrivate(keySpec);
} catch (Exception e) {
throw e;
}
}
/**
* 载入公钥
* @param publicKeyKeyStr
* @return
* @throws Exception
*/
public static PublicKey loadPublicKey(String publicKeyKeyStr) throws Exception{
try {
byte[] buffer= Base64.decode(publicKeyKeyStr);
KeyFactory keyFactory= KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec= new X509EncodedKeySpec(buffer);
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
throw new Exception("无此算法");
} catch (NullPointerException e) {
throw new Exception("公钥数据为空");
} catch (Exception e) {
throw e;
}
}
/**
* 把key=value追加到加密/签名字符串最后.
*
* @param buf
* @param key
* @param value
*/
public static void appendSignPara(StringBuffer buf, String key, String value) {
if (!StringUtils.isEmpty(value)) {
buf.append(key).append('=').append(value).append('&');
}
}
/**
* 把key=value追加到加密/签名字符串的末尾.字符串不再继续增加新的key=value.
*
* @param buf
* @param key
* @param value
*/
public static void appendLastSignPara(StringBuffer buf, String key,
String value) {
if (!StringUtils.isEmpty(value)) {
buf.append(key).append('=').append(value);
}
}
/**
* key=value排序
*
* @param map
*/
public static String orderMap2Str(Map<String, Object> map) {
Set<String> keySet = new TreeSet(map.keySet());
StringBuilder sb = new StringBuilder();
for (String key : keySet) {
if (Map.class.isInstance(map.get(key))
|| List.class.isInstance(map.get(key))
|| StringUtils.isEmpty(String.valueOf(map.get(key)))
|| "sign".equals(key)) {
continue;
}
sb.append(key).append("=").append(map.get(key)).append("&");
}
sb.setLength(sb.length() - 1);
return sb.toString();
}
/**
* sha1计算后进行16进制转换
*
* @param data
* 待计算的数据
* @param encoding
* 编码
* @return 计算结果
*/
public static byte[] sha1X16(String data, String encoding) {
byte[] bytes = sha1(data, encoding);
StringBuilder sha1StrBuff = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
if (Integer.toHexString(0xFF & bytes[i]).length() == 1) {
sha1StrBuff.append("0").append(
Integer.toHexString(0xFF & bytes[i]));
} else {
sha1StrBuff.append(Integer.toHexString(0xFF & bytes[i]));
}
}
try {
return sha1StrBuff.toString().getBytes(encoding);
} catch (UnsupportedEncodingException e) {
return null;
}
}
/**
* sha1计算
*
* @param datas
* 待计算的数据
* @param encoding
* 字符集编码
* @return
*/
private static byte[] sha1(String datas, String encoding) {
try {
return sha1(datas.getBytes(encoding));
} catch (UnsupportedEncodingException e) {
return null;
}
}
/**
* sha1计算.
*
* @param datas
* 待计算的数据
* @return 计算结果
*/
private static byte[] sha1(byte[] data) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-1");
md.reset();
md.update(data);
return md.digest();
} catch (Exception e) {
return null;
}
}
/**
* sha256计算后进行16进制转换
*
* @param data
* 待计算的数据
* @param encoding
* 编码
* @return 计算结果
*/
public static byte[] sha256X16(String data, String encoding) {
byte[] bytes = sha256(data, encoding);
StringBuilder sha256StrBuff = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
if (Integer.toHexString(0xFF & bytes[i]).length() == 1) {
sha256StrBuff.append("0").append(
Integer.toHexString(0xFF & bytes[i]));
} else {
sha256StrBuff.append(Integer.toHexString(0xFF & bytes[i]));
}
}
try {
return sha256StrBuff.toString().getBytes(encoding);
} catch (UnsupportedEncodingException e) {
return null;
}
}
/**
* sha256计算
*
* @param datas
* 待计算的数据
* @param encoding
* 字符集编码
* @return
*/
private static byte[] sha256(String datas, String encoding) {
try {
return sha256(datas.getBytes(encoding));
} catch (UnsupportedEncodingException e) {
return null;
}
}
/**
* sha256计算.
*
* @param datas
* 待计算的数据
* @return 计算结果
*/
private static byte[] sha256(byte[] data) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-256");
md.reset();
md.update(data);
return md.digest();
} catch (Exception e) {
return null;
}
}
/*public static void main(String[] args) {
try {
FileInputStream privateStream = new FileInputStream("C:\\testPrivate.key");
FileInputStream publicKeyStream = new FileInputStream("C:\\testPublic.key");
String privateKeyStr = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqt4f8zgcfdu2w7IS" + "\r" +
"6rUyiLIQmOnIDj9HBcFy5NcoBoDpiSJ7txmqBtKO0pANrso6Zu5jIBxcgFC1qZPv" + "\r" +
"gsJh6QIDAQABAkAsNnnR94z3zCiIjsVyUhyXXmwJBUUs2pbIGHxgVoQW2kwbTnxw" + "\r" +
"I2u7IhGUPpW7duzOxA2Kk1Msr79SX88vKjB5AiEA31WlZZGZxQ/V6o5H0NsUifs/" + "\r" +
"OSVWk5N9ofBmqq9WdxMCIQDD2/POZnm0+yBRcdb8ozYIQSkbFdeKqyR5pof5Fso2" + "\r" +
"kwIgbQnGt+EvfzvtCBixTXI5A+kMBB2LuH+RHgheR8VVZMsCICQ97CRyQ+0gVv+b" + "\r" +
"IBwJm3L1k8SmSwcm2g4Eqb6G4A4vAiEAkV5fULSax5TFW3n5k8FA51YhgGlFeWhy" + "\r" +
"q/rDpEC+VrU="+ "\r";
String publicKeyKeyStr = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKreH/M4HH3btsOyEuq1MoiyEJjpyA4/" + "\r" +
"RwXBcuTXKAaA6Ykie7cZqgbSjtKQDa7KOmbuYyAcXIBQtamT74LCYekCAwEAAQ=="+ "\r";
String publicCertUrl = "/app/conf/mchtCert";
FileInputStream privateStream = new FileInputStream("C:\\private.key");
FileInputStream publicKeyStream = new FileInputStream("C:\\public.key");
String signSrc="1111123wwwqq";
//签名
// PrivateKey privateKey = loadPrivateKeyWithPcks8(privateKeyStr);
PrivateKey privateKey = loadPrivateKey(privateStream,"PCKS8");
String signMac=new String(Base64.encode(signByPriKey(privateKey,signSrc.getBytes(),"MD5WithRSA")));
System.out.println(signMac);
//验签
// PublicKey publickey=loadPublicKey(publicKeyKeyStr);
PublicKey publickey =loadPublicKey(publicKeyStream);
boolean result=verifyByPubKey(publickey,signSrc.getBytes(),Base64.decode(signMac),"MD5WithRSA");
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}*/
public static void main(String[] args) {
String signSrc="merchantId=008310107630117&requestDatetime=203010121820001&signType=4";
//签名
// PrivateKey privateKey = loadPrivateKeyWithPcks8(privateKeyStr);
PrivateKey privateKey;
try {
privateKey = getPrivateKey("00ac007886a8173f45e9f84d7dce522569aa8a12d296c8182f651983f42f15f5c1956b714ba13ee89a5d97ae4a07e1738c9f4528703f2ba00768da49856a4794f4c50b2c56ef696d2252fe88e3ceb04a2da6d79bb77fb77999eb054f47dab0afbfd5ebbb432b68326c75ad50ee4904b3f4230a57878a757b8f8b2e65c79237c0a30f4dcf53553028aa2bcd74bac984d1f7d9ba591bf541ea97c499f5e3c289d3bec89bd7f86b910a6a35bd13604fd7af9a82ab9ca0fdb0ad60258072200be57315006616a56dfc5d09de0aad45c73986812e16fe03525cdac9cbeae5c6a7778b1e5f4d27b48c41a0f1b512a41b5eb50567b98c28db9b09d24636106d484172249d","009c08214e26965033e037fc3430429ce5ea6b2f00130099d004eacca56b41849b842cdfae382c955dd3a191de5e9fcaeeba5d467ded106a2fce9297378c5e3b668089ce435f14488866b9b8fccfb764d35d132293a82c8d077008750f3df822b6e81cdcd7e63cb3e1682f3dc7ac3db3f1b907dcb77c876efb9ccb0e51a8f722ac4998562dc08bf6cc24fe9fe7925b0ad03195ec6cac354ec0a536b020e5f93fac73f16e50566db725efcdd59d23a9cf793ae3859c03ed9667ab0d4f13a041afb53ad0497c375f08291b0117840dba958d5fa8dcccea0f99f9a605e28b36187dfc1f7ddc513d700b83522ba217c7c38e0168252175def31458ae104e1c87bcd601");
String signMac=new String(Base64.encode(signByPriKey(privateKey,signSrc.getBytes(),"SHA1WithRSA")));
System.out.println(signMac);
//验签
// PublicKey publickey=loadPublicKey(publicKeyKeyStr);
PublicKey publickey =getPublicKey("00ac007886a8173f45e9f84d7dce522569aa8a12d296c8182f651983f42f15f5c1956b714ba13ee89a5d97ae4a07e1738c9f4528703f2ba00768da49856a4794f4c50b2c56ef696d2252fe88e3ceb04a2da6d79bb77fb77999eb054f47dab0afbfd5ebbb432b68326c75ad50ee4904b3f4230a57878a757b8f8b2e65c79237c0a30f4dcf53553028aa2bcd74bac984d1f7d9ba591bf541ea97c499f5e3c289d3bec89bd7f86b910a6a35bd13604fd7af9a82ab9ca0fdb0ad60258072200be57315006616a56dfc5d09de0aad45c73986812e16fe03525cdac9cbeae5c6a7778b1e5f4d27b48c41a0f1b512a41b5eb50567b98c28db9b09d24636106d484172249d","010001");
boolean result=verifyByPubKey(publickey,signSrc.getBytes(),Base64.decode(signMac),"SHA1WithRSA");
System.out.println(result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
解释:
前一个main方法测试公私钥密文传输,后一个main方法测试公私钥明文传输。
公私钥生成方式,可以利用linux 使用openssl生成pkcs1格式秘钥:
私钥openssl genrsa -out private.key 512
公钥openssl rsa -in private.key -pubout -out public.key
提取当前文件目录里面的字符串秘钥,这种方式产生的是密文公私钥,拷贝出来即可使用。
另外需注意的是加密算法和解密算法一定要保持一致。