SignatureProgram.java
import com.alibaba.fastjson.JSON;
import com.bestpay.mobilebiz.mapi.common.util.Base64Encrypt;
import com.bestpay.mobilebiz.mapi.common.util.CryptoUtil;
import com.bestpay.mobilebiz.mapi.common.util.KeyCertInfo;
import com.bestpay.mobilebiz.mapi.common.util.SignatureUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.IOException;
import java.io.InputStream;
import java.security.*;
import java.security.cert.X509Certificate;
import java.util.*;
/**
* @Description:
* @Date: 2017/9/8
*/
public class SignatureProgram {
public static void main(String[] args) throws GeneralSecurityException, IOException {
//--------------生成签名demo------------
InputStream resourceAsStream = Program.class.getClassLoader().getResourceAsStream("用户证书.p12");
String passwd = "bestpay1";
String alias = "conname";
String keyStoreType = "PKCS12";
KeyCertInfo keyCertInfo = CryptoUtil.fileStreamToKeyCertInfo(resourceAsStream,passwd,keyStoreType,alias);
BouncyCastleProvider bouncyCastleProvider = new BouncyCastleProvider();
Signature signature = Signature.getInstance("SHA256withRSA",bouncyCastleProvider);
//请求参数
Map translateResultData=new HashMap<>();
translateResultData.put("institutionCode","3178000003978343");
translateResultData.put("merchantNo","8630029000159147");
translateResultData.put("outTradeNo","201709191472852012807774852354");
translateResultData.put("tradeAmt","11");
translateResultData.put("subject","subject");
translateResultData.put("productCode","68800020109");
translateResultData.put("buyerLoginNo","18691832778");
translateResultData.put("ccy","156");
translateResultData.put("requestDate","2017-09-19 23:59:15");
translateResultData.put("operator","operator");
translateResultData.put("ledgerAccount","ledgerAccount");
translateResultData.put("notifyUrl","notifyUrl");
translateResultData.put("timeOut","0");
translateResultData.put("storeCode","storeCode");
translateResultData.put("storeName","storeName");
translateResultData.put("goodsInfo","goodsInfo");
translateResultData.put("remark","remark");
String content = assembelSignaturingData(translateResultData);
String sign = SignatureUtil.sign(signature,content, (PrivateKey) keyCertInfo.getPrivateKey());
translateResultData.put("sign",sign);
System.out.println(JSON.toJSONString(translateResultData));
//--------------生成签名demo------------
//--------------验证翼支付签名demo------------
String jsonS="{\"errorCode\":\"DUIPLICAT_ORDER_ERROR\",\"errorMsg\":\"重复下单\",\"result\":null,\"sign\":\"n0EPUQ5fHpnnaxM7A84P7CKE4MXGvZuB7szIZx7VwCnjRfWs+6G+B0I+ay2IeJQufBn9ukfCPS0jgZsRWxy91g0SWWxCQFq7qhE3oTFG5xj7zC0Cl18r1I7F5OUfq3SpeiLSXTWwNOeayUbzyMtVJAeWosGv0f9mTKhgWf0s0Rs=\",\"success\":false}";
Map mapTypes = JSON.parseObject(jsonS);
String checksign = String.valueOf(mapTypes.get("sign"));
String checkContent = assembelSignaturingData(mapTypes);
System.out.println(checkContent);
InputStream pubStream = SignatureProgram.class.getClassLoader().getResourceAsStream("服务器证书.crt");
byte pubByte[] = new byte[2048] ;
pubStream.read(pubByte);
pubStream.close();
X509Certificate x509Certificate = CryptoUtil.base64StrToCert(Base64Encrypt.getBASE64ForByte(pubByte));
BouncyCastleProvider bouncyCastleProvider2 = new BouncyCastleProvider();
Signature signatureCheck = Signature.getInstance("SHA1withRSA",bouncyCastleProvider2);
boolean isOk = SignatureUtil.verify(signatureCheck,checkContent,checksign,x509Certificate.getPublicKey());
System.out.println(isOk);
//--------------验证翼支付签名demo------------
}
//顺序组装请求参数,用于签名/校验
static String assembelSignaturingData(Map data) {
StringBuilder sb = new StringBuilder();
TreeMap treeMap = new TreeMap(data);
for (Map.Entry ent : treeMap.entrySet()) {
String name = ent.getKey();
if (/* !"signType".equals(name) &&*/ !"sign".equals(name)) {
sb.append(name).append('=').append(ent.getValue()).append('&');
}
}
if (sb.length() > 0) {
sb.setLength(sb.length() - 1);
}
return sb.toString();
}
}
Base64Encrypt.java
package com.bestpay.mobilebiz.mapi.common.util;
import org.apache.commons.lang3.StringUtils;
import java.io.UnsupportedEncodingException;
import java.util.Base64;
/**
* Base64加解密工具
* @version 1.0.0
* @time 2015/07/07
*/
public class Base64Encrypt {
/***
* BASE64加密
* @param s 字符串
* @return
*/
public static String getBASE64(String s) {
if(StringUtils.isEmpty(s)){
return null;
}
Base64.Encoder encoder = Base64.getEncoder();
try {
byte [] bytes = s.getBytes("UTF-8");
return encoder.encodeToString(bytes);
} catch (UnsupportedEncodingException e) {
return null;
}
}
/***
* BASE64加密
* @param s 字节
* @return
*/
public static String getBASE64ForByte(byte[] s) {
if (s == null)
return null;
return Base64.getEncoder().encodeToString(s);
}
/***
* BASE64解密
* @param s 字符串
* @return
* @throws Exception
*/
public static byte[] getByteArrFromBase64(String s) throws Exception {
if (s == null)
return null;
return Base64.getDecoder().decode(s);
}
/***
* BASE64解密
* @param s
* @return
*/
public static String getFromBASE64(String s) {
Base64.Decoder decoder = Base64.getDecoder();
try {
byte[] b = decoder.decode(s);
return new String(b);
} catch (Exception e) {
return null;
}
}
/***
* 将 BASE64 编码的字符串 s 进行解码
* @param s 字符串
* @param charset 编码
* @return
*/
public static String getFromBASE64(String s, String charset) {
Base64.Decoder decoder = Base64.getDecoder();
try {
byte[] b = decoder.decode(s);
return new String(b, charset);
} catch (Exception e) {
return null;
}
}
}
CryptoUtil.java
package com.bestpay.mobilebiz.mapi.common.util;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;
import sun.misc.BASE64Decoder;
import javax.crypto.Cipher;
import java.io.*;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* @Description:
* @Date: 2017/8/7
* @Moidfy by:
*/
public class CryptoUtil {
private static BouncyCastleProvider bouncyCastleProvider;
private static final Object LOCK = new Object();
private static CertificateFactory factory = initFactory();
private static CertificateFactory initFactory() {
try {
return CertificateFactory.getInstance("X.509");
} catch (CertificateException var1) {
throw new RuntimeException(var1);
}
}
/**
* @desc SHA256 加密公共类
* @author liujianqun
* @method getSHA256
* @param str 加密字符串
* @return java.lang.String
*/
public static String getSHA256(String str,String algorithm){
MessageDigest messageDigest;
String encdeStr = "";
try {
messageDigest = MessageDigest.getInstance(algorithm);
byte[] hash = messageDigest.digest(str.getBytes("UTF-8"));
encdeStr = Hex.encodeHexString(hash);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return encdeStr;
}
public static String getSHA256Com(String str)
{
MessageDigest md = null;
String result = "";
try {
md = MessageDigest.getInstance("SHA-256");
md.update(str.getBytes("utf-8"));
byte[] digest = md.digest();
result=new String (Base64.encode(digest));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
public static byte[] getSHA256Byte(String str,String algorithm){
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance(algorithm);
byte[] hash = messageDigest.digest(str.getBytes("UTF-8"));
return hash;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
private static BouncyCastleProvider getInstanceProvider() {
if(bouncyCastleProvider == null) {
Object var0 = LOCK;
synchronized(LOCK) {
if(bouncyCastleProvider == null) {
bouncyCastleProvider = new BouncyCastleProvider();
}
}
}
return bouncyCastleProvider;
}
public static byte[] enDecryptByRsa(byte[] data, Key key, int mode) throws GeneralSecurityException {
BouncyCastleProvider provider = getInstanceProvider();
ByteArrayOutputStream outputStream = null;
byte[] var21;
try {
outputStream = new ByteArrayOutputStream();
Cipher cp = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
cp.init(mode, key);
int blockSize = cp.getBlockSize();
int blocksNum = (int)Math.ceil((double)data.length / (double)blockSize);
int calcSize = blockSize;
Object buffer = null;
for(int i = 0; i < blocksNum; ++i) {
if(i == blocksNum - 1) {
calcSize = data.length - i * blockSize;
}
byte[] var22 = cp.doFinal(data, i * blockSize, calcSize);
try {
outputStream.write(var22);
} catch (IOException var19) {
throw new GeneralSecurityException("RSA加/解密时出现异常", var19);
}
}
var21 = outputStream.toByteArray();
} finally {
if(outputStream != null) {
try {
outputStream.close();
} catch (IOException var18) {
}
}
}
return var21;
}
public static X509Certificate base64StrToCert(String base64Cert) throws GeneralSecurityException {
try {
ByteArrayInputStream ex = new ByteArrayInputStream((new BASE64Decoder()).decodeBuffer(base64Cert));
X509Certificate cert = (X509Certificate)factory.generateCertificate(ex);
if(cert == null) {
throw new GeneralSecurityException("将cer从base64转换为对象失败");
} else {
return cert;
}
} catch (IOException var3) {
throw new GeneralSecurityException("将cer从base64转换为对象失败", var3);
}
}
public static String signWithSHA2(InputStream fisP12, String pwd, String plainText)
{
String result ="";
KeyStore inputKeyStore = null;
try {
if (fisP12 == null ||(pwd == null) || (plainText == null) || (pwd.equals("")) || (plainText.equals("")) ) {
return result;
}
inputKeyStore = KeyStore.getInstance("PKCS12");
char[] inPassword = (pwd == null) ? null : pwd.toCharArray();
inputKeyStore.load(fisP12, inPassword);
// fisP12.close();
PrivateKey privateKey = (PrivateKey)inputKeyStore.getKey("conname", inPassword);
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(plainText.getBytes("utf-8"));
byte[] digest = md.digest();
// String digestText = new String(Base64.encode(digest));
byte[] signData = RsaCipher.enDecryptByRsa(digest, privateKey, RsaCipher.EncryptMode.ENCRYPT);
result = new String(Base64.encode(signData));
return result;
/* 获取证书
X509Certificate x509Certificate = (X509Certificate)inputKeyStore.getCertificate("conname");
byte[] encoded = x509Certificate.getEncoded();
String base64Cert = new String(Base64.encode(encoded));*/
} catch (Exception e) {
return "";
}
}
public static String getCert(InputStream fisP12, String pwd)
{
char[] inPassword = (pwd == null) ? null : pwd.toCharArray();
try {
KeyStore inputKeyStore = KeyStore.getInstance("PKCS12");
inputKeyStore.load(fisP12, inPassword);
// fisP12.close();
X509Certificate x509Certificate = (X509Certificate)inputKeyStore.getCertificate("conname");
byte[] encoded = x509Certificate.getEncoded();
return new String(Base64.encode(encoded));
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
///alias = conname
public static KeyCertInfo fileStreamToKeyCertInfo(InputStream fisP12, String pwd, String keyStoreType, String alias){
KeyCertInfo result = null;
try {
KeyStore inputKeyStore = KeyStore.getInstance(keyStoreType);
char[] inPassword = (pwd == null) ? null : pwd.toCharArray();
inputKeyStore.load(fisP12, inPassword);
PrivateKey privateKey = (PrivateKey)inputKeyStore.getKey(alias, inPassword);
X509Certificate x509Certificate = (X509Certificate)inputKeyStore.getCertificate(alias);
byte[] encoded = x509Certificate.getEncoded();
String base64Cert = new String(Base64.encode(encoded));
result = new KeyCertInfo();
result.setBase64Cert(base64Cert);
result.setPrivateKey(privateKey);
return result;
} catch (Exception e) {
return result;
}
}
public static String signWithSHA2(String plainText,Key privateKey)
{
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-256");
md.update(plainText.getBytes("utf-8"));
byte[] digest = md.digest();
byte[] signData = RsaCipher.enDecryptByRsa(digest, privateKey, RsaCipher.EncryptMode.ENCRYPT);
return new String(Base64.encode(signData));
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
public static byte[] getSHA2Digest(String plainText)
{
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-256");
md.update(plainText.getBytes("utf-8"));
byte[] digest = md.digest();
return digest;
}catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String signWithBase(byte[] digest,Key privateKey)
{
MessageDigest md = null;
try {
byte[] signData = RsaCipher.enDecryptByRsa(digest, privateKey, RsaCipher.EncryptMode.ENCRYPT);
return new String(Base64.encode(signData));
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
public static PrivateKey byte2PrivateKey(byte[] src,String algorithm)
{
try {
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);//"RSA"
PKCS8EncodedKeySpec pKCS8EncodedKeySpec =new PKCS8EncodedKeySpec(src);
PrivateKey privateKey= keyFactory.generatePrivate(pKCS8EncodedKeySpec);
return privateKey;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
} catch (InvalidKeySpecException e) {
e.printStackTrace();
return null;
}
}
public static PublicKey byte2PublicKey(byte[] src,String algorithm)
{
try {
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);//"RSA"
X509EncodedKeySpec x509KeySpec2 = new X509EncodedKeySpec(src);
PublicKey privateKey= keyFactory.generatePublic(x509KeySpec2);
return privateKey;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
} catch (InvalidKeySpecException e) {
e.printStackTrace();
return null;
}
}
}
KeyCertInfo.java
package com.bestpay.mobilebiz.mapi.common.util;
import java.security.Key;
/**
* Created by on 2017/8/19.
*/
public class KeyCertInfo {
public Key getPrivateKey() {
return privateKey;
}
public void setPrivateKey(Key privateKey) {
this.privateKey = privateKey;
}
public String getBase64Cert() {
return base64Cert;
}
public void setBase64Cert(String base64Cert) {
this.base64Cert = base64Cert;
}
private Key privateKey;
private String base64Cert;
}
RsaCipher.java
package com.bestpay.mobilebiz.mapi.common.util;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import sun.security.rsa.RSAPublicKeyImpl;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.interfaces.RSAPublicKey;
public abstract class RsaCipher
{
public static final Object LOCK = new Object();
private static BouncyCastleProvider bouncyCastleProvider;
public static byte[] enDecryptByRsa(byte[] data, Key key, int mode)
throws GeneralSecurityException
{
byte[] var21;
BouncyCastleProvider provider = getInstanceProvider();
ByteArrayOutputStream outputStream = null;
try
{
outputStream = new ByteArrayOutputStream();
Cipher cp = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
cp.init(mode, key);
int blockSize = cp.getBlockSize();
int blocksNum = (int)Math.ceil((double) data.length / (double)blockSize);
int calcSize = blockSize;
Object buffer = null;
for (int i = 0; i < blocksNum; ++i) {
if (i == blocksNum - 1) {
calcSize = data.length - i * blockSize;
}
byte[] var22 = cp.doFinal(data, i * blockSize, calcSize);
try
{
outputStream.write(var22);
} catch (IOException var19) {
throw new GeneralSecurityException("RSA加/解密时出现异常", var19);
}
}
var21 = outputStream.toByteArray();
} finally {
if (outputStream != null)
try {
outputStream.close();
}
catch (IOException var18)
{
}
}
return var21;
}
public static RSAPublicKey restoreKeyByModules(String modulesHex) throws GeneralSecurityException {
BigInteger modules = new BigInteger(modulesHex, 16);
BigInteger publicExponent = new BigInteger("65537");
RSAPublicKeyImpl rsaPublicKey = new RSAPublicKeyImpl(modules, publicExponent);
return rsaPublicKey;
}
public static byte[] enDecryptByRsa(byte[] data, Key key, EncryptMode mode) throws GeneralSecurityException {
return enDecryptByRsa(data, key, 1 + mode.ordinal());
}
private static BouncyCastleProvider getInstanceProvider() {
if (bouncyCastleProvider == null) {
Object var0 = LOCK;
synchronized (LOCK) {
if (bouncyCastleProvider == null)
bouncyCastleProvider = new BouncyCastleProvider();
}
}
return bouncyCastleProvider; }
public static enum EncryptMode {
ENCRYPT, DECRYPT;
}
}
SignatureUtil.java
package com.bestpay.mobilebiz.mapi.common.util;
import org.apache.commons.codec.binary.Base64;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
/**
* @Author:
* @Description:
* @Date: 2017/9/7
* @Moidfy by:
*/
public class SignatureUtil {
private static final String charcterCode = "UTF-8";
/**
* SHA256WithRSA签名
* @param data
* @param privateKey
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws InvalidKeyException
* @throws SignatureException
* @throws UnsupportedEncodingException
*/
public static String sign(Signature signature,String data, PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException,
SignatureException, UnsupportedEncodingException {
signature.initSign(privateKey);
signature.update(data.getBytes(charcterCode));
byte[] signBytes = signature.sign();
return new String (org.bouncycastle.util.encoders.Base64.encode(signBytes));
}
public static boolean verify(Signature signature,String data, String sign, PublicKey publicKey) throws UnsupportedEncodingException {
if(data == null || sign == null || publicKey == null){
return false;
}
byte[] signBytes = org.bouncycastle.util.encoders.Base64.decode(sign.getBytes(charcterCode));
try {
signature.initVerify(publicKey);
signature.update(data.getBytes(charcterCode));
return signature.verify(signBytes);
} catch (Exception e) {
return false;
}
}
/**
* 二进制数据编码为BASE64字符串
* @param bytes
* @return
*/
public static String encodeBase64(byte[] bytes){
return new String(Base64.encodeBase64(bytes));
}
/**
* BASE64解码
* @param bytes
* @return
*/
public static byte[] decodeBase64(byte[] bytes) {
byte[] result = null;
try {
result = Base64.decodeBase64(bytes);
} catch (Exception e) {
return null;
}
return result;
}
//顺序组装请求参数,用于签名/校验
static String assembelSignaturingData(Map data) {
StringBuilder sb = new StringBuilder();
TreeMap treeMap = new TreeMap(data);
for (Map.Entry ent : treeMap.entrySet()) {
String name = ent.getKey();
if (/* !"signType".equals(name) &&*/ !"sign".equals(name)) {
sb.append(name).append('=').append(ent.getValue()).append('&');
}
}
if (sb.length() > 0) {
sb.setLength(sb.length() - 1);
}
return sb.toString();
}
}