MD5及公私钥数据加密工具类

加签验签代码如下:

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

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

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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值