package com.taxi591.bankapi.service;
|
|
import com.taxi591.bankapi.BankProperties;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.codec.binary.Base64;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.stereotype.Component;
|
|
import javax.servlet.http.HttpServletRequest;
|
import java.io.*;
|
import java.security.KeyStore;
|
import java.security.PrivateKey;
|
import java.security.PublicKey;
|
import java.security.Signature;
|
import java.security.cert.CertificateFactory;
|
import java.security.cert.X509Certificate;
|
import java.util.Enumeration;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* 验签和加签工具类
|
* @author yzz
|
*
|
*/
|
@Component
|
@Slf4j
|
public class SignatureAndVerification {
|
|
@Autowired
|
BankProperties bankProperties;
|
|
|
|
public static String getRequestBody(HttpServletRequest request)
|
throws IOException {
|
/** 读取httpbody内容 */
|
StringBuilder httpBody = new StringBuilder();
|
BufferedReader br = null;
|
try {
|
br = new BufferedReader(new InputStreamReader(
|
request.getInputStream()));
|
String line = null;
|
while ((line = br.readLine()) != null) {
|
httpBody.append(line);
|
}
|
} catch (IOException ex) {
|
throw ex;
|
} finally {
|
if (br != null) {
|
try {
|
br.close();
|
} catch (IOException ex) {
|
ex.printStackTrace();
|
}
|
}
|
}
|
return httpBody.toString();
|
}
|
/**
|
* 加签名
|
* @param dataString
|
* @return
|
*/
|
public String signWhithsha1withrsa(String dataString) {
|
String signatureString = null;
|
String filePath=bankProperties.getPfxPath();
|
try {
|
KeyStore ks = KeyStore.getInstance("PKCS12");
|
FileInputStream fis = new FileInputStream(filePath);
|
char[] nPassword = null;
|
if ((bankProperties.getKeystorePassword() == null)
|
|| bankProperties.getKeystorePassword().trim().equals("")) {
|
nPassword = null;
|
} else {
|
nPassword = bankProperties.getKeystorePassword().toCharArray();
|
}
|
ks.load(fis, nPassword);
|
fis.close();
|
|
Enumeration<String> enums = ks.aliases();
|
String keyAlias = null;
|
if (enums.hasMoreElements())
|
{
|
keyAlias = (String) enums.nextElement();
|
}
|
System.out.println("is key entry=" + ks.isKeyEntry(keyAlias));
|
PrivateKey prikey = (PrivateKey) ks.getKey(keyAlias, nPassword);
|
java.security.cert.Certificate cert = ks.getCertificate(keyAlias);
|
// SHA1withRSA算法进行签名
|
Signature sign = Signature.getInstance("SHA1withRSA");
|
sign.initSign(prikey);
|
byte[] data = dataString.getBytes("utf-8");
|
byte[] dataBase= Base64.encodeBase64(data);
|
// 更新用于签名的数据
|
sign.update(dataBase);
|
byte[] signature = sign.sign();
|
signatureString = new String(Base64.encodeBase64(signature));
|
System.out.println("加密完成,signature is : " + signatureString);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return signatureString;
|
}
|
|
/**
|
* 读取cer并验证公钥签名
|
* @return
|
*/
|
public boolean read_cer_and_verify_sign(String requestBody, String signature) {
|
String filePath=bankProperties.getCerPath();
|
X509Certificate cert = null;
|
boolean flag = false;
|
try {
|
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
cert = (X509Certificate) cf
|
.generateCertificate(new FileInputStream(new File(
|
filePath)));
|
PublicKey publicKey = cert.getPublicKey();
|
String publicKeyString = new String(Base64.encodeBase64(publicKey
|
.getEncoded()));
|
System.out.println("-----------------公钥--------------------");
|
System.out.println(publicKeyString);
|
System.out.println("-----------------公钥--------------------");
|
Signature verifySign = Signature.getInstance("SHA1withRSA");
|
verifySign.initVerify(publicKey);
|
// 用于验签的数据
|
verifySign.update(requestBody.getBytes("utf-8"));
|
flag = verifySign.verify(Base64
|
.decodeBase64(signature));
|
} catch (Exception e) {
|
log.error("验签失败,发生异常:{},{}",requestBody,signature,e);
|
flag = false;
|
}
|
return flag;
|
}
|
|
/**
|
* 接收报文返回requestBody和使用base64解析后的requestBody以及缴费中心传送的签名
|
*/
|
|
public Map<String,String> requestBodyOfBase64(HttpServletRequest request){
|
Map<String,String> requestMap=new HashMap<String,String>();
|
// 接收报文
|
String requestContent=null;
|
try {
|
requestContent = getRequestBody(request)
|
.trim();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
String signatureString = null;
|
String requestBody = null;
|
if (requestContent.contains("||")) {
|
signatureString = requestContent.substring(0,
|
requestContent.indexOf("||"));
|
requestBody = requestContent.substring(signatureString
|
.length() + 2);
|
}else {
|
try {
|
requestBody = new String(requestContent.getBytes("GB2312"));
|
|
log.info("转码后的报文:{}",requestBody);
|
|
} catch (UnsupportedEncodingException e) {
|
e.printStackTrace();
|
}
|
}
|
log.info("截取报文的requestBody解密前:{}", requestBody);
|
|
String requestBodyOfDecoded = new String(
|
Base64.decodeBase64(requestBody));
|
|
/*if (requestBodyOfDecoded.contains("</Message>")) {
|
requestBody = requestBodyOfDecoded.substring(
|
requestContent.indexOf("</Message>"),requestContent.indexOf("</Message>")+10);
|
|
signatureString = requestBodyOfDecoded.substring(
|
requestContent.indexOf("<Signature>")+11,requestContent.indexOf("</Signature>"));
|
}*/
|
|
log.info("截取报文的signatureString:{}", signatureString);
|
|
|
System.out.println("-----解析完成后的requestBody-------" + requestBodyOfDecoded);
|
|
//使用base64解析完成后的requestBody
|
requestMap.put("requestBodyOfDecoded",requestBodyOfDecoded);
|
//解析前的requestBody
|
requestMap.put("requestBody",requestBody);
|
//获取缴费中心传送过来的签名
|
requestMap.put("signatureString",signatureString);
|
return requestMap;
|
|
}
|
|
}
|