欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

提取当前文件目录里面的字符串秘钥,这种方式产生的是密文公私钥,拷贝出来即可使用。

另外需注意的是加密算法和解密算法一定要保持一致。