jar:com.cfca.pkibase-1.0.jar

import java.io.UnsupportedEncodingException;

import java.security.Security;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import com.cfca.util.pki.PKIException;

import com.cfca.util.pki.api.CertUtil;

import com.cfca.util.pki.api.KeyUtil;

import com.cfca.util.pki.api.SignatureUtil;

import com.cfca.util.pki.cert.X509Cert;

import com.cfca.util.pki.cipher.JCrypto;

import com.cfca.util.pki.cipher.JKey;

import com.cfca.util.pki.cipher.Session;

import com.cfca.util.pki.extension.SelfDefExtension;

/**

* <pre>

* CFCA证书工具类

* help:http://www.360doc.com/content/13/0831/06/11482448_311087429.shtml

* @version:1.0

* </pre>

*/

public class CFCACertSignUtils {

private static Session session = null;

private static final String ALGORITHM = SignatureUtil.SHA1_RSA;

public static final String DEFAULT_CHARSET = "UTF-8";

public static String lock = "LOCK";

public static final String YEEPAY_IDENTITY = "OU=ra.yeepay.com";

public static final String CERT_EXT_INFO = new String("1.2.86.1");

static {

try {

Security.addProvider(new BouncyCastleProvider());

} catch (Exception e) {

e.printStackTrace();

}

}

private synchronized static void init() {

if (session != null) {

return;

}

try {

JCrypto jcrypto = JCrypto.getInstance();

jcrypto.initialize(JCrypto.JSOFT_LIB, null);

session = jcrypto.openSession(JCrypto.JSOFT_LIB);

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 获取证书的私钥对象信息

*

* @param certPath

*            CFCA pfx格式证书文件路径

* @param certPswd

*            CFCA证书密码

* @return

*/

public static JKey getPrivaeKey(String certPath, String certPswd)

throws PKIException {

return KeyUtil.getPriKey(certPath, certPswd);

}

/**

* 获取证书的公钥对象信息

*

* @param certPath

*            CFCA pfx格式证书文件路径

* @param certPswd

*            CFCA证书密码

* @return

*/

public static X509Cert getPublicKey(String certPath, String certPswd)

throws PKIException {

return CertUtil.getCert(certPath, certPswd);

}

/**

* CFCA非分离式PKCS#7签名--验签需要对应非分离式验签方法verifySignMessageP7

*

* @param sourceMessage

*            源消息

* @param privateKey

*            私钥

* @param publicKey

*            公钥

* @return

*/

public static String sign(String sourceMessage, JKey privateKey,

X509Cert[] publicKey, String charset) {

if (session == null) {

init();

}

try {

String yphs = Digest.hmacSign(sourceMessage, charset);

SignatureUtil signUtil = new SignatureUtil();

byte[] input = null;

if (charset == null) {

input = yphs.getBytes();

} else {

input = yphs.getBytes(charset);

}

// 对消息签名

byte[] b64SignData;

b64SignData = signUtil.p7SignMessage(true, input, ALGORITHM, privateKey, publicKey, session);

String signMessage = new String(b64SignData, DEFAULT_CHARSET);

return signMessage;

} catch (Exception e) {

throw new RuntimeException("签名失败!", e);

}

}

/**

* <pre>

* 验证签名的合法性 验证商户的CFCA非分离式PKCS#7签名 (验证签名信息的完整性和不可抵赖性)

*

* @param sourceMessage

*            商户原始交易数据

* @param signMessage

*            CFCA签名结果(Base64编码)以UTF-8编码成的字符串

* @param customerNo

*            客户号(验证当前证书是否是授予该客户的证书)

* @return X509Cert[] 验签通过后返回签名证书的公钥信息

* @throws UnsupportedEncodingException

* @throws PKIException

* </pre>

*/

public static boolean verifySign(String sourceMessage, String signMessage,

String customerNo) {

if (customerNo == null) {

throw new IllegalArgumentException("当前业务客户号未指定");

}

if (session == null) {

init();

}

try {

SignatureUtil signUtil = new SignatureUtil();

// 对原始交易数据做hash摘要

String digestMsg = Digest.hmacSign(sourceMessage, DEFAULT_CHARSET);

byte signData[] = signMessage.getBytes(DEFAULT_CHARSET);// 再以UTF-8编码方式解码成字节数组

boolean verify = signUtil.p7VerifySignMessage(signData, session);// 1.验证签名的不可抵赖性

if (verify) {// 签名

// 获得签名中的证书

X509Cert x509Certs = signUtil.getSigerCert()[0];

// 获得签名数据中的原文

byte[] srcData = signUtil.getSignedContent();// 原始hash值的BASE64编码

String reverseHashMessage = new String(srcData, DEFAULT_CHARSET);

// 证书所有者身份校验

identityVerify(customerNo, x509Certs);

if (reverseHashMessage.equals(digestMsg)) {// 2.原始数据得到的摘要和验签得到的原始摘要做比较验证数据的完整性

return true;

} else {

throw new RuntimeException("消息摘要信息不一致,信息可能被篡改!");

}

} else {

throw new RuntimeException("验签失败");

}

} catch (Exception e) {

throw new RuntimeException(e);

}

}

// 证书所有者身份校验

private static void identityVerify(String customerNo, X509Cert x509Certs)

throws PKIException {

String certDN = x509Certs.getSubject();

boolean isValidecertDN = false;

String certDNItems[] = certDN.split(",");

for (String item : certDNItems) {

if (item.equals(YEEPAY_IDENTITY)) {

isValidecertDN = true;

}

}

if (!isValidecertDN) {

throw new RuntimeException("不是yeepay颁发的CFCA证书");

}

String extension = null;

SelfDefExtension extensionInfo = x509Certs

.getSelfDefExtension(CERT_EXT_INFO);

if (extensionInfo == null) {

throw new RuntimeException("证书扩展信息未指定,无法识别客户身份信息");

}

extension = extensionInfo.getExtensionValue();

if (extension == null) {

throw new RuntimeException("证书扩展信息未指定,无法识别客户身份信息");

}

if (!customerNo.equals(extension)) {

throw new RuntimeException("当前证书不是颁发给客户[" + customerNo + "]的证书!");

}

}

}

最新文章

  1. JavaScript校验图片格式及大小
  2. python2.79安装
  3. 【网络编程】之十二、wsaeventselect+线程池 服务器实现
  4. java工厂类与反射机制
  5. Nagios利用NSClient++监控Windows主机
  6. Vbox创建COM对象失败
  7. PowerDesigner中逆向工程将数据库中comment赋值到name
  8. javascript设计模式——迭代器模式
  9. SpringBoot之GZip压缩,HTTP/2,文件上传,缓存配置
  10. 初识hibernate——环境搭建
  11. centos下如何使用sendmail发送邮件
  12. Jquery 插件 图片验证码
  13. POJO与PO、VO的区别
  14. 原生 JS 实现移动端 Touch 滑动反弹
  15. An integration of deep learning and neuroscience
  16. Python Logger使用
  17. session.upload_progress.enabled开启的问题
  18. moment.js使用方法总结
  19. 669. Trim a Binary Search Tree修剪二叉搜索树
  20. linux-centos6②

热门文章

  1. ansible运维工具,dhcp,cobbler
  2. jar - 操作jar包的工具
  3. django项目使用layui插件给网站设置一个日历挂件,很简单实用。
  4. 记一次用pip安装docker-compose报错及解决方法
  5. 转 OJDBC驱动版本区别 [ojdbc14.jar,ojdbc5.jar跟ojdbc6.jar的区别]
  6. node 日志 log4js 错误日志记录
  7. GlusterFS集群文件系统研究
  8. SpringMVC_原理(转)
  9. Git的个人总结
  10. S1_搭建分布式OpenStack集群_10 cinder 存储节点配置