CFCA证书工具类
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 + "]的证书!"); } } } |
CFCA证书工具类的更多相关文章
- HttpClient4.5 SSL访问工具类
要从网上找一个HttpClient SSL访问工具类太难了,原因是HttpClient版本太多了,稍有差别就不能用,最后笔者干脆自己封装了一个访问HTTPS并绕过证书工具类. 主要是基于新版本Http ...
- 我的Android进阶之旅------>Android关于HttpsURLConnection一个忽略Https证书是否正确的Https请求工具类
下面是一个Android HttpsURLConnection忽略Https证书是否正确的Https请求工具类,不需要验证服务器端证书是否正确,也不需要验证服务器证书中的域名是否有效. (PS:建议下 ...
- 带SSL证书的httpclient 远程接口工具类
package com.iups.wx.util; import java.io.IOException; import java.io.UnsupportedEncodingException; i ...
- java http工具类和HttpUrlConnection上传文件分析
利用java中的HttpUrlConnection上传文件,我们其实只要知道Http协议上传文件的标准格式.那么就可以用任何一门语言来模拟浏览器上传文件.下面有几篇文章从http协议入手介绍了java ...
- 微信https请求工具类
工作中用到的微信https请求工具类. package com.gxgrh.wechat.tools; import com.gxgrh.wechat.wechatapi.service.System ...
- HttpClient 4.5.x 工具类设计与实现
最近,业务需要在java服务端发起http请求,需要实现"GET","POST","PUT"等基本方法.于是想以 "HttpCli ...
- Net处理html页面元素工具类(HtmlAgilityPack.dll)的使用
现在,在不少应用场合中都希望做到数据抓取,特别是基于网页部分的抓取.其实网页抓取的过程实际上是通过编程的方法,去抓取不同网站网页后,再进行 分析筛选的过程.比如,有的比较购物网站,会同时去抓取不同购物 ...
- 基于HttpClient 4.3的可訪问自签名HTTPS网站的新版工具类
本文出处:http://blog.csdn.net/chaijunkun/article/details/40145685,转载请注明.因为本人不定期会整理相关博文,会对相应内容作出完好.因此强烈建议 ...
- java中模拟http(https)请求的工具类
在java中,特别是java web中,我们经常需要碰到的一个场景是我们需要从服务端去发送http请求,获取到数据,而不是直接从浏览器输入请求网址获得相应.比如我们想访问微信接口,获取其返回信息. 在 ...
随机推荐
- scrapy框架用CrawlSpider类爬取电影天堂.
本文使用CrawlSpider方法爬取电影天堂网站内国内电影分类下的所有电影的名称和下载地址 CrawlSpider其实就是Spider的一个子类. CrawlSpider功能更加强大(链接提取器,规 ...
- Linux系统文件/etc/fstab
挂载可以使用命令或者修改系统文件两种方式,第一种方式使用mount命令挂载文件系统可以立即生效并使用,但计算机重启后无效.另一种方式需要修改系统文件/etc/fstab,这种方式挂载的文件系统在计算机 ...
- drf序列化器与反序列化
什么是序列化与反序列化 """ 序列化:对象转换为字符串用于传输 反序列化:字符串转换为对象用于使用 """ drf序列化与反序列化 &qu ...
- 项目Alpha冲刺--8/10
项目Alpha冲刺--8/10 作业要求 这个作业属于哪个课程 软件工程1916-W(福州大学) 这个作业要求在哪里 项目Alpha冲刺 团队名称 基于云的胜利冲锋队 项目名称 云评:高校学生成绩综合 ...
- Yii集成PHPWord
一.安装 1.下载composer curl -sS https://getcomposer.org/installer | php 将composer.phar文件移动到bin目录以便全局使用com ...
- 关于Java的i++和++i的区别
之前对于 i++ 和 ++i 的理解就是: int i=1,a=0; 1.i++ 先运算在赋值,例如 a=i++,先运算a=i,后运算i=i+1,所以结果是a==1 2.++i 先赋值在运算,例如 a ...
- Sql语句中Like嵌套用法
一般的Like用法: SELECT U_NAME FROM T_USER WHERE U_NAME LIKE '%A%' 但是,我此次like关键字后面的对应值是一个变量,需要用select语句来实现 ...
- Codeforces Round #605 (Div. 3) A. Three Friends(贪心)
链接: https://codeforces.com/contest/1272/problem/A 题意: outputstandard output Three friends are going ...
- LeetCode 1011. Capacity To Ship Packages Within D Days
原题链接在这里:https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/ 题目: A conveyor belt h ...
- tensorflow2.0 学习(一)
虽说是按<TensorFlow深度学习>这本书来学习的,但是总会碰到新的问题!记录下这些问题,有利于巩固知新. 之前学过一些tensorflow1.0的知识,到RNN这章节,后面没有再继续 ...