支付宝证书公钥实现方式

This commit is contained in:
egzosn
2020-10-12 22:52:22 +08:00
parent c5604f5d3a
commit 708a7b16b6
17 changed files with 3371 additions and 170 deletions

View File

@@ -1,11 +1,10 @@
package com.egzosn.pay.common.api;
import com.egzosn.pay.common.bean.CertStoreType;
import com.egzosn.pay.common.bean.MsgType;
import com.egzosn.pay.common.util.sign.CertDescriptor;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import com.egzosn.pay.common.bean.MsgType;
/**
* 支付基础配置存储
@@ -24,10 +23,7 @@ public abstract class BasePayConfigStorage implements PayConfigStorage {
* 应用私钥rsa_private pkcs8格式 生成签名时使用
*/
private String keyPrivate;
/**
* 应用私钥证书rsa_private pkcs8格式 生成签名时使用
*/
private String keyPrivateCertPwd;
/**
* 支付平台公钥(签名校验使用)
*/
@@ -58,21 +54,22 @@ public abstract class BasePayConfigStorage implements PayConfigStorage {
/**
* 消息来源类型
*/
@Deprecated
private MsgType msgType;
/**
* 访问令牌 每次请求其他方法都要传入的值
*/
private String accessToken;
private volatile String accessToken;
/**
* access token 到期时间时间戳
*/
private long expiresTime;
private volatile long expiresTime;
/**
* 授权码锁
*/
private Lock accessTokenLock = new ReentrantLock();
private Lock accessTokenLock;
/**
* 是否为沙箱环境,默认为正式环境
*/
@@ -81,8 +78,12 @@ public abstract class BasePayConfigStorage implements PayConfigStorage {
/**
* 是否为证书签名
*/
private boolean isCertSign = false;
private boolean certSign = false;
/**
* 配置附加信息,可用于预设未提供的参数,这里会覆盖以上所有的配置信息,
*/
private volatile Map<String, Object> attr;
@Override
public Object getAttach() {
@@ -102,14 +103,6 @@ public abstract class BasePayConfigStorage implements PayConfigStorage {
this.keyPrivate = keyPrivate;
}
@Override
public String getKeyPrivateCertPwd() {
return keyPrivateCertPwd;
}
public void setKeyPrivateCertPwd(String keyPrivateCertPwd) {
this.keyPrivateCertPwd = keyPrivateCertPwd;
}
@Override
public String getKeyPublic() {
@@ -173,23 +166,31 @@ public abstract class BasePayConfigStorage implements PayConfigStorage {
public void setMsgType(MsgType msgType) {
this.msgType = msgType;
}
@Override
/**
* 获取访问令牌
* @return 访问令牌
*/
public String getAccessToken() {
return this.accessToken;
}
@Override
/**
* 获取access token锁
* @return access token锁
*/
public Lock getAccessTokenLock() {
return this.accessTokenLock;
}
@Override
/**
* 强制将access token过期掉
* @return 过期时间
*/
public long getExpiresTime() {
return expiresTime;
}
@Override
/**
* 访问令牌是否过期
* @return true过期
*/
public boolean isAccessTokenExpired() {
return System.currentTimeMillis() > this.expiresTime;
}
@@ -197,8 +198,7 @@ public abstract class BasePayConfigStorage implements PayConfigStorage {
@Override
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
this.accessToken = accessToken;
this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 600) * 1000L;
updateAccessToken(accessToken, System.currentTimeMillis() + (expiresInSeconds - 600) * 1000L);
}
@Override
@@ -207,7 +207,10 @@ public abstract class BasePayConfigStorage implements PayConfigStorage {
this.expiresTime = expiresTime;
}
@Override
/**
* 强制将access token过期掉
*/
public void expireAccessToken() {
this.expiresTime = 0;
}
@@ -239,12 +242,33 @@ public abstract class BasePayConfigStorage implements PayConfigStorage {
}
public boolean isCertSign() {
return isCertSign;
return certSign;
}
public void setCertSign(boolean certSign) {
isCertSign = certSign;
this.certSign = certSign;
}
@Override
public Map<String, Object> getAttrs() {
if (null == attr){
attr = new HashMap<>();
}
return attr;
}
@Override
public Object getAttr(String key) {
return getAttrs().get(key);
}
/**
* 添加配置信息
* @param key key
* @param value 值
*/
public void addAttr(String key, Object value) {
getAttrs().put(key, value);
}
}

View File

@@ -18,5 +18,5 @@ public interface CertStore {
* @return 输入流
* @throws IOException 找不到文件异常
*/
public abstract InputStream getInputStream(Object cert) throws IOException;
InputStream getInputStream(Object cert) throws IOException;
}

View File

@@ -1,5 +1,6 @@
package com.egzosn.pay.common.api;
import com.egzosn.pay.common.bean.Attrs;
import com.egzosn.pay.common.bean.MsgType;
import com.egzosn.pay.common.util.sign.CertDescriptor;
@@ -13,7 +14,7 @@ import java.util.concurrent.locks.Lock;
* date 2016-5-18 14:09:01
* </pre>
*/
public interface PayConfigStorage {
public interface PayConfigStorage extends Attrs {
/**
* 附加支付配置
@@ -21,11 +22,6 @@ import java.util.concurrent.locks.Lock;
*/
Object getAttach();
/**
* 获取私钥证书密码
* @return 私钥证书密码
*/
String getKeyPrivateCertPwd();
/**
* 应用id
* @return 应用id
@@ -98,35 +94,11 @@ import java.util.concurrent.locks.Lock;
* @see MsgType
* @return "text" 或者 "xml"json
*/
@Deprecated
MsgType getMsgType();
/**
* 获取访问令牌
* @return 访问令牌
*/
String getAccessToken();
/**
* 访问令牌是否过期
* @return true过期
*/
boolean isAccessTokenExpired();
/**
* 获取access token锁
* @return access token锁
*/
Lock getAccessTokenLock();
/**
* 强制将access token过期掉
*/
void expireAccessToken();
/**
* 强制将access token过期掉
* @return 过期时间
*/
long getExpiresTime();
/**
* 应该是线程安全的
@@ -150,5 +122,4 @@ import java.util.concurrent.locks.Lock;
}

View File

@@ -0,0 +1,31 @@
package com.egzosn.pay.common.bean;
import java.io.Serializable;
import java.util.Map;
/**
* 属性信息
*
* @author Egan
* <pre>
* email egzosn@gmail.com
* date 2020/10/8
* </pre>
*/
public interface Attrs extends Serializable {
/**
* 获取属性 这里可用做覆盖已设置的信息属性,订单信息在签名前进行覆盖。
*
* @return 属性
*/
Map<String, Object> getAttrs();
/**
* 获取属性 这里可用做覆盖已设置的订单信息属性,订单信息在签名前进行覆盖。
*
* @param key 属性名
* @return 属性
*/
Object getAttr(String key);
}

View File

@@ -1,6 +1,8 @@
package com.egzosn.pay.common.bean;
import com.egzosn.pay.common.api.CertStore;
import com.egzosn.pay.common.bean.result.PayException;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.common.http.HttpRequestTemplate;
import java.io.*;
@@ -15,7 +17,23 @@ import java.io.*;
public enum CertStoreType implements CertStore {
/**
* 路径,建议绝对路径
* 无存储类型,表示无需要转换为输入流
*/
NONE{
/**
* 证书信息转化为对应的输入流
*
* @param cert 证书信息
* @return 输入流
* @throws IOException 找不到文件异常
*/
@Override
public InputStream getInputStream(Object cert) throws IOException {
return null;
}
},
/**
* 文件路径,建议绝对路径
*/
PATH {
/**
@@ -30,6 +48,22 @@ public enum CertStoreType implements CertStore {
return new FileInputStream(new File((String) cert));
}
},
/**
* class路径
*/
CLASS_PATH {
/**
* 证书信息转化为对应的输入流
*
* @param cert 证书信息
* @return 输入流
* @throws IOException 找不到文件异常
*/
@Override
public InputStream getInputStream(Object cert) throws IOException {
return Thread.currentThread().getContextClassLoader().getResourceAsStream((String) cert);
}
},
/**
* 文件流转化成字符串存储至文件或者数据库中
*/
@@ -98,14 +132,10 @@ public enum CertStoreType implements CertStore {
Class<?> clazz = Class.forName((String) beanClazz);
CertStore certStore = (CertStore)clazz.newInstance();
return certStore.getInputStream(beanClazz);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ReflectiveOperationException e) {
throw new PayErrorException(new PayException("证书获取异常", e.getMessage()));
}
return null;
}
};

View File

@@ -12,22 +12,7 @@ import java.util.Map;
* date 2020/01/05 13:34
* </pre>
*/
public interface Order extends Serializable {
/**
* 获取订单属性 这里可用做覆盖已设置的订单信息属性,订单信息在签名前进行覆盖。
*
* @return 属性
*/
Map<String, Object> getAttrs();
/**
* 获取订单属性 这里可用做覆盖已设置的订单信息属性,订单信息在签名前进行覆盖。
*
* @param key 属性名
* @return 属性
*/
Object getAttr(String key);
public interface Order extends Attrs {
/**

View File

@@ -18,6 +18,7 @@ import java.util.Map;
*/
public class PayMessage implements Serializable {
private Map<String, Object> payMessage = null;
@Deprecated
private String msgType;
private String payType;
private String transactionType;
@@ -50,10 +51,12 @@ public class PayMessage implements Serializable {
this.payMessage = payMessage;
}
@Deprecated
public String getMsgType() {
return msgType;
}
@Deprecated
public void setMsgType(String msgType) {
this.msgType = msgType;
}

View File

@@ -90,7 +90,7 @@ public class PayOrder implements Order {
/**
* 订单附加信息,可用于预设未提供的参数,这里会覆盖以上所有的订单信息,
*/
private Map<String, Object> attr;
private volatile Map<String, Object> attr;
public PayOrder() {

File diff suppressed because it is too large Load Diff

View File

@@ -60,7 +60,7 @@ public class SecureUtil {
*/
public static byte[] sha1X16 (String data, String encoding) {
try {
byte[] bytes = digestByData(data.getBytes(encoding),ALGORITHM_SHA1);
byte[] bytes = digestByData(data.getBytes(encoding), ALGORITHM_SHA1);
StringBuilder sha1StrBuff = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
if (Integer.toHexString(0xFF & bytes[i]).length() == 1) {
@@ -91,7 +91,7 @@ public class SecureUtil {
public static String sha256X16Str(String data, String encoding) {
byte[] bytes =null;
try {
bytes = digestByData(data.getBytes(encoding),ALGORITHM_SHA1);
bytes = digestByData(data.getBytes(encoding), ALGORITHM_SHA1);
} catch (UnsupportedEncodingException e) {
throw new PayErrorException(new PayException("error", e.getLocalizedMessage()));
}