CertUtil.java 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. /**
  2. *
  3. * Licensed Property to China UnionPay Co., Ltd.
  4. *
  5. * (C) Copyright of China UnionPay Co., Ltd. 2010
  6. * All Rights Reserved.
  7. *
  8. *
  9. * Modification History:
  10. * =============================================================================
  11. * Author Date Description
  12. * ------------ ---------- ---------------------------------------------------
  13. * xshu 2014-05-28 证书工具类.
  14. * =============================================================================
  15. */
  16. package com.itstyle.modules.unionpay.util;
  17. import java.io.File;
  18. import java.io.FileInputStream;
  19. import java.io.FileNotFoundException;
  20. import java.io.FilenameFilter;
  21. import java.io.IOException;
  22. import java.math.BigInteger;
  23. import java.security.KeyFactory;
  24. import java.security.KeyStore;
  25. import java.security.KeyStoreException;
  26. import java.security.NoSuchAlgorithmException;
  27. import java.security.NoSuchProviderException;
  28. import java.security.PrivateKey;
  29. import java.security.Provider;
  30. import java.security.PublicKey;
  31. import java.security.Security;
  32. import java.security.UnrecoverableKeyException;
  33. import java.security.cert.Certificate;
  34. import java.security.cert.CertificateException;
  35. import java.security.cert.CertificateFactory;
  36. import java.security.cert.X509Certificate;
  37. import java.security.spec.RSAPublicKeySpec;
  38. import java.util.Enumeration;
  39. import java.util.HashMap;
  40. import java.util.Map;
  41. import java.util.concurrent.ConcurrentHashMap;
  42. import org.slf4j.Logger;
  43. import org.slf4j.LoggerFactory;
  44. import static com.itstyle.modules.unionpay.util.SDKUtil.isEmpty;
  45. public class CertUtil {
  46. private static final Logger logger = LoggerFactory.getLogger(CertUtil.class);
  47. /** 证书容器. */
  48. private static KeyStore keyStore = null;
  49. /** 密码加密证书 */
  50. private static X509Certificate encryptCert = null;
  51. // /** 磁道加密证书 */
  52. // private static X509Certificate encryptTrackCert = null;
  53. /** 磁道加密公钥 */
  54. private static PublicKey encryptTrackKey = null;
  55. /** 验证签名证书. */
  56. private static X509Certificate validateCert = null;
  57. /** 验签证书存储Map. */
  58. private static Map<String, X509Certificate> certMap = new HashMap<String, X509Certificate>();
  59. /** 根据传入证书文件路径和密码读取指定的证书容器.(一种线程安全的实现方式) */
  60. private final static ThreadLocal<KeyStore> certKeyStoreLocal = new ThreadLocal<KeyStore>();
  61. /** 基于Map存储多商户RSA私钥 */
  62. private final static Map<String, KeyStore> certKeyStoreMap = new ConcurrentHashMap<String, KeyStore>();
  63. static {
  64. init();
  65. }
  66. /**
  67. * 添加签名,验签,加密算法提供者
  68. */
  69. private static void addProvider(){
  70. if (Security.getProvider("BC") == null) {
  71. logger.info("add BC provider");
  72. Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
  73. } else {
  74. Security.removeProvider("BC"); //解决eclipse调试时tomcat自动重新加载时,BC存在不明原因异常的问题。
  75. Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
  76. logger.info("re-add BC provider");
  77. }
  78. printSysInfo();
  79. }
  80. /**
  81. * 初始化所有证书.
  82. */
  83. public static void init() {
  84. addProvider();
  85. if (SDKConstants.TRUE_STRING.equals(SDKConfig.getConfig()
  86. .getSingleMode())) {
  87. // 单证书模式,初始化配置文件中的签名证书
  88. initSignCert();
  89. }
  90. initEncryptCert();// 初始化加密公钥证书
  91. initTrackKey();
  92. initValidateCertFromDir();// 初始化所有的验签证书
  93. }
  94. /**
  95. * 加载签名证书
  96. */
  97. public static void initSignCert() {
  98. if (null != keyStore) {
  99. keyStore = null;
  100. }
  101. try {
  102. keyStore = getKeyInfo(SDKConfig.getConfig().getSignCertPath(),
  103. SDKConfig.getConfig().getSignCertPwd(), SDKConfig
  104. .getConfig().getSignCertType());
  105. logger.info("InitSignCert Successful. CertId=["
  106. + getSignCertId() + "]");
  107. } catch (IOException e) {
  108. logger.error("InitSignCert Error", e);
  109. }
  110. }
  111. /**
  112. * 根据传入的证书文件路径和证书密码加载指定的签名证书
  113. * @deprecated
  114. */
  115. public static void initSignCert(String certFilePath, String certPwd) {
  116. logger.info("加载证书文件[" + certFilePath + "]和证书密码[" + certPwd
  117. + "]的签名证书开始.");
  118. certKeyStoreLocal.remove();
  119. File files = new File(certFilePath);
  120. if (!files.exists()) {
  121. logger.info("证书文件不存在,初始化签名证书失败.");
  122. return;
  123. }
  124. try {
  125. certKeyStoreLocal.set(getKeyInfo(certFilePath, certPwd, "PKCS12"));
  126. } catch (IOException e) {
  127. logger.error("加载签名证书失败", e);
  128. }
  129. logger.info("加载证书文件[" + certFilePath + "]和证书密码[" + certPwd
  130. + "]的签名证书结束.");
  131. }
  132. /**
  133. * 加载RSA签名证书
  134. *
  135. * @param certFilePath
  136. * @param certPwd
  137. */
  138. public static void loadRsaCert(String certFilePath, String certPwd) {
  139. KeyStore keyStore = null;
  140. try {
  141. keyStore = getKeyInfo(certFilePath, certPwd, "PKCS12");
  142. certKeyStoreMap.put(certFilePath, keyStore);
  143. logger.info("LoadRsaCert Successful");
  144. } catch (IOException e) {
  145. logger.error("LoadRsaCert Error", e);
  146. }
  147. }
  148. /**
  149. * 加载密码加密证书 目前支持有两种加密
  150. */
  151. private static void initEncryptCert() {
  152. logger.info("加载敏感信息加密证书==>"+SDKConfig.getConfig().getEncryptCertPath());
  153. if (!isEmpty(SDKConfig.getConfig().getEncryptCertPath())) {
  154. encryptCert = initCert(SDKConfig.getConfig().getEncryptCertPath());
  155. logger.info("LoadEncryptCert Successful");
  156. } else {
  157. logger.info("WARN: acpsdk.encryptCert.path is empty");
  158. }
  159. // if (!isEmpty(SDKConfig.getConfig().getEncryptTrackCertPath())) {
  160. // encryptTrackCert = initCert(SDKConfig.getConfig()
  161. // .getEncryptTrackCertPath());
  162. // logger.info("LoadEncryptTrackCert Successful");
  163. // } else {
  164. // logger.info("WARN: acpsdk.encryptTrackCert.path is empty");
  165. // }
  166. }
  167. /**
  168. * 加载磁道公钥
  169. */
  170. private static void initTrackKey() {
  171. if (!isEmpty(SDKConfig.getConfig().getEncryptTrackKeyModulus())
  172. && !isEmpty(SDKConfig.getConfig().getEncryptTrackKeyExponent())) {
  173. encryptTrackKey = SecureUtil.getPublicKey(SDKConfig.getConfig().getEncryptTrackKeyModulus(),
  174. SDKConfig.getConfig().getEncryptTrackKeyExponent());
  175. logger.info("LoadEncryptTrackKey Successful");
  176. } else {
  177. logger.info("WARN: acpsdk.encryptTrackKey.modulus or acpsdk.encryptTrackKey.exponent is empty");
  178. }
  179. }
  180. /**
  181. *
  182. * @param path
  183. * @return
  184. */
  185. private static X509Certificate initCert(String path) {
  186. X509Certificate encryptCertTemp = null;
  187. CertificateFactory cf = null;
  188. FileInputStream in = null;
  189. try {
  190. cf = CertificateFactory.getInstance("X.509", "BC");
  191. in = new FileInputStream(path);
  192. encryptCertTemp = (X509Certificate) cf.generateCertificate(in);
  193. // 打印证书加载信息,供测试阶段调试
  194. logger.info("[" + path + "][CertId="
  195. + encryptCertTemp.getSerialNumber().toString() + "]");
  196. } catch (CertificateException e) {
  197. logger.error("InitCert Error", e);
  198. } catch (FileNotFoundException e) {
  199. logger.error("InitCert Error File Not Found", e);
  200. } catch (NoSuchProviderException e) {
  201. logger.error("LoadVerifyCert Error No BC Provider", e);
  202. } finally {
  203. if (null != in) {
  204. try {
  205. in.close();
  206. } catch (IOException e) {
  207. logger.error("initCert方法",e);
  208. }
  209. }
  210. }
  211. return encryptCertTemp;
  212. }
  213. /**
  214. * 从指定目录下加载验证签名证书
  215. *
  216. */
  217. private static void initValidateCertFromDir() {
  218. certMap.clear();
  219. String dir = SDKConfig.getConfig().getValidateCertDir();
  220. logger.info("加载验证签名证书目录==>" + dir);
  221. if (isEmpty(dir)) {
  222. logger.info("ERROR: acpsdk.validateCert.dir is empty");
  223. return;
  224. }
  225. CertificateFactory cf = null;
  226. FileInputStream in = null;
  227. try {
  228. cf = CertificateFactory.getInstance("X.509", "BC");
  229. File fileDir = new File(dir);
  230. File[] files = fileDir.listFiles(new CerFilter());
  231. for (int i = 0; i < files.length; i++) {
  232. File file = files[i];
  233. in = new FileInputStream(file.getAbsolutePath());
  234. validateCert = (X509Certificate) cf.generateCertificate(in);
  235. certMap.put(validateCert.getSerialNumber().toString(),
  236. validateCert);
  237. // 打印证书加载信息,供测试阶段调试
  238. logger.info("[" + file.getAbsolutePath() + "][CertId="
  239. + validateCert.getSerialNumber().toString() + "]");
  240. }
  241. logger.info("LoadVerifyCert Successful");
  242. } catch (CertificateException e) {
  243. logger.error("LoadVerifyCert Error", e);
  244. } catch (FileNotFoundException e) {
  245. logger.error("LoadVerifyCert Error File Not Found", e);
  246. } catch (NoSuchProviderException e) {
  247. logger.error("LoadVerifyCert Error No BC Provider", e);
  248. } finally {
  249. if (null != in) {
  250. try {
  251. in.close();
  252. } catch (IOException e) {
  253. logger.error("initValidateCertFromDir方法",e);
  254. }
  255. }
  256. }
  257. }
  258. /**
  259. * 获取签名证书私钥(单证书模式)
  260. *
  261. * @return
  262. */
  263. public static PrivateKey getSignCertPrivateKey() {
  264. try {
  265. Enumeration<String> aliasenum = keyStore.aliases();
  266. String keyAlias = null;
  267. if (aliasenum.hasMoreElements()) {
  268. keyAlias = aliasenum.nextElement();
  269. }
  270. PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias,
  271. SDKConfig.getConfig().getSignCertPwd().toCharArray());
  272. return privateKey;
  273. } catch (KeyStoreException e) {
  274. logger.error("getSignCertPrivateKey Error", e);
  275. return null;
  276. } catch (UnrecoverableKeyException e) {
  277. logger.error("getSignCertPrivateKey Error", e);
  278. return null;
  279. } catch (NoSuchAlgorithmException e) {
  280. logger.error("getSignCertPrivateKey Error", e);
  281. return null;
  282. }
  283. }
  284. /**
  285. * 通过传入证书绝对路径和证书密码获取所对应的签名证书私钥
  286. *
  287. * @param certPath
  288. * 证书绝对路径
  289. * @param certPwd
  290. * 证书密码
  291. * @return 证书私钥
  292. *
  293. * @deprecated
  294. */
  295. public static PrivateKey getSignCertPrivateKeyByThreadLocal(
  296. String certPath, String certPwd) {
  297. if (null == certKeyStoreLocal.get()) {
  298. // 初始化指定certPath和certPwd的签名证书容器
  299. initSignCert(certPath, certPwd);
  300. }
  301. try {
  302. Enumeration<String> aliasenum = certKeyStoreLocal.get().aliases();
  303. String keyAlias = null;
  304. if (aliasenum.hasMoreElements()) {
  305. keyAlias = aliasenum.nextElement();
  306. }
  307. PrivateKey privateKey = (PrivateKey) certKeyStoreLocal.get()
  308. .getKey(keyAlias, certPwd.toCharArray());
  309. return privateKey;
  310. } catch (Exception e) {
  311. logger.error("获取[" + certPath + "]的签名证书的私钥失败", e);
  312. return null;
  313. }
  314. }
  315. public static PrivateKey getSignCertPrivateKeyByStoreMap(String certPath,
  316. String certPwd) {
  317. if (!certKeyStoreMap.containsKey(certPath)) {
  318. loadRsaCert(certPath, certPwd);
  319. }
  320. try {
  321. Enumeration<String> aliasenum = certKeyStoreMap.get(certPath)
  322. .aliases();
  323. String keyAlias = null;
  324. if (aliasenum.hasMoreElements()) {
  325. keyAlias = aliasenum.nextElement();
  326. }
  327. PrivateKey privateKey = (PrivateKey) certKeyStoreMap.get(certPath)
  328. .getKey(keyAlias, certPwd.toCharArray());
  329. return privateKey;
  330. } catch (KeyStoreException e) {
  331. logger.error("getSignCertPrivateKeyByStoreMap Error", e);
  332. return null;
  333. } catch (UnrecoverableKeyException e) {
  334. logger.error("getSignCertPrivateKeyByStoreMap Error", e);
  335. return null;
  336. } catch (NoSuchAlgorithmException e) {
  337. logger.error("getSignCertPrivateKeyByStoreMap Error", e);
  338. return null;
  339. }
  340. }
  341. /**
  342. * 获取加密证书公钥.密码加密时需要
  343. *
  344. * @return
  345. */
  346. public static PublicKey getEncryptCertPublicKey() {
  347. if (null == encryptCert) {
  348. String path = SDKConfig.getConfig().getEncryptCertPath();
  349. if (!isEmpty(path)) {
  350. encryptCert = initCert(path);
  351. return encryptCert.getPublicKey();
  352. } else {
  353. logger.info("ERROR: acpsdk.encryptCert.path is empty");
  354. return null;
  355. }
  356. } else {
  357. return encryptCert.getPublicKey();
  358. }
  359. }
  360. /**
  361. * 获取加密证书公钥.密码加密时需要
  362. * 加密磁道信息证书
  363. *
  364. * @return
  365. */
  366. public static PublicKey getEncryptTrackPublicKey() {
  367. // if (null == encryptTrackCert) {
  368. // String path = SDKConfig.getConfig().getEncryptTrackCertPath();
  369. // if (!isEmpty(path)) {
  370. // encryptTrackCert = initCert(path);
  371. // return encryptTrackCert.getPublicKey();
  372. // } else {
  373. // logger.info("ERROR: acpsdk.encryptTrackCert.path is empty");
  374. // return null;
  375. // }
  376. // } else {
  377. // return encryptTrackCert.getPublicKey();
  378. // }
  379. if (null == encryptTrackKey) {
  380. initTrackKey();
  381. }
  382. return encryptTrackKey;
  383. }
  384. /**
  385. * 验证签名证书
  386. *
  387. * @return 验证签名证书的公钥
  388. */
  389. public static PublicKey getValidateKey() {
  390. if (null == validateCert) {
  391. return null;
  392. }
  393. return validateCert.getPublicKey();
  394. }
  395. /**
  396. * 通过certId获取证书Map中对应证书的公钥
  397. *
  398. * @param certId
  399. * 证书物理序号
  400. * @return 通过证书编号获取到的公钥
  401. */
  402. public static PublicKey getValidateKey(String certId) {
  403. X509Certificate cf = null;
  404. if (certMap.containsKey(certId)) {
  405. // 存在certId对应的证书对象
  406. cf = certMap.get(certId);
  407. return cf.getPublicKey();
  408. } else {
  409. // 不存在则重新Load证书文件目录
  410. initValidateCertFromDir();
  411. if (certMap.containsKey(certId)) {
  412. // 存在certId对应的证书对象
  413. cf = certMap.get(certId);
  414. return cf.getPublicKey();
  415. } else {
  416. logger.info("缺少certId=[" + certId + "]对应的验签证书.");
  417. return null;
  418. }
  419. }
  420. }
  421. /**
  422. * 获取签名证书中的证书序列号(单证书)
  423. *
  424. * @return 证书的物理编号
  425. */
  426. public static String getSignCertId() {
  427. try {
  428. Enumeration<String> aliasenum = keyStore.aliases();
  429. String keyAlias = null;
  430. if (aliasenum.hasMoreElements()) {
  431. keyAlias = aliasenum.nextElement();
  432. }
  433. X509Certificate cert = (X509Certificate) keyStore
  434. .getCertificate(keyAlias);
  435. return cert.getSerialNumber().toString();
  436. } catch (Exception e) {
  437. logger.error("getSignCertId Error", e);
  438. return null;
  439. }
  440. }
  441. /**
  442. * 获取加密证书的证书序列号
  443. *
  444. * @return
  445. */
  446. public static String getEncryptCertId() {
  447. if (null == encryptCert) {
  448. String path = SDKConfig.getConfig().getEncryptCertPath();
  449. if (!isEmpty(path)) {
  450. encryptCert = initCert(path);
  451. return encryptCert.getSerialNumber().toString();
  452. } else {
  453. logger.info("ERROR: acpsdk.encryptCert.path is empty");
  454. return null;
  455. }
  456. } else {
  457. return encryptCert.getSerialNumber().toString();
  458. }
  459. }
  460. /**
  461. * 获取磁道加密证书的证书序列号
  462. * @deprecated 磁道根本没给证书啊啊啊啊啊啊啊
  463. * @return
  464. */
  465. public static String getEncryptTrackCertId() {
  466. // if (null == encryptTrackCert) {
  467. // String path = SDKConfig.getConfig().getEncryptTrackCertPath();
  468. // if (!isEmpty(path)) {
  469. // encryptTrackCert = initCert(path);
  470. // return encryptTrackCert.getSerialNumber().toString();
  471. // } else {
  472. // logger.info("ERROR: acpsdk.encryptTrackCert.path is empty");
  473. // return null;
  474. // }
  475. // } else {
  476. // return encryptTrackCert.getSerialNumber().toString();
  477. // }
  478. return "";
  479. }
  480. /**
  481. * 获取签名证书公钥对象
  482. *
  483. * @return
  484. */
  485. public static PublicKey getSignPublicKey() {
  486. try {
  487. Enumeration<String> aliasenum = keyStore.aliases();
  488. String keyAlias = null;
  489. if (aliasenum.hasMoreElements()) // we are readin just one
  490. // certificate.
  491. {
  492. keyAlias = (String) aliasenum.nextElement();
  493. }
  494. Certificate cert = keyStore.getCertificate(keyAlias);
  495. PublicKey pubkey = cert.getPublicKey();
  496. return pubkey;
  497. } catch (Exception e) {
  498. logger.error("获取签名证书公钥对象",e);
  499. return null;
  500. }
  501. }
  502. /**
  503. * 将证书文件读取为证书存储对象
  504. *
  505. * @param pfxkeyfile
  506. * 证书文件名
  507. * @param keypwd
  508. * 证书密码
  509. * @param type
  510. * 证书类型
  511. * @return 证书对象
  512. * @throws IOException
  513. */
  514. public static KeyStore getKeyInfo(String pfxkeyfile, String keypwd,
  515. String type) throws IOException {
  516. logger.info("加载签名证书==>" + pfxkeyfile);
  517. FileInputStream fis = null;
  518. try {
  519. KeyStore ks = KeyStore.getInstance(type, "BC");
  520. logger.info("Load RSA CertPath=[" + pfxkeyfile + "],Pwd=["+ keypwd + "],type=["+type+"]");
  521. fis = new FileInputStream(pfxkeyfile);
  522. char[] nPassword = null;
  523. nPassword = null == keypwd || "".equals(keypwd.trim()) ? null: keypwd.toCharArray();
  524. if (null != ks) {
  525. ks.load(fis, nPassword);
  526. }
  527. return ks;
  528. } catch (Exception e) {
  529. if (Security.getProvider("BC") == null) {
  530. logger.info("BC Provider not installed.");
  531. }
  532. logger.error("getKeyInfo Error", e);
  533. if ((e instanceof KeyStoreException) && "PKCS12".equals(type)) {
  534. Security.removeProvider("BC");
  535. }
  536. return null;
  537. } finally {
  538. if(null!=fis)
  539. fis.close();
  540. }
  541. }
  542. // 打印系统环境信息
  543. public static void printSysInfo() {
  544. logger.info("================= SYS INFO begin====================");
  545. logger.info("os_name:" + System.getProperty("os.name"));
  546. logger.info("os_arch:" + System.getProperty("os.arch"));
  547. logger.info("os_version:" + System.getProperty("os.version"));
  548. logger.info("java_vm_specification_version:"
  549. + System.getProperty("java.vm.specification.version"));
  550. logger.info("java_vm_specification_vendor:"
  551. + System.getProperty("java.vm.specification.vendor"));
  552. logger.info("java_vm_specification_name:"
  553. + System.getProperty("java.vm.specification.name"));
  554. logger.info("java_vm_version:"
  555. + System.getProperty("java.vm.version"));
  556. logger.info("java_vm_name:" + System.getProperty("java.vm.name"));
  557. logger.info("java.version:" + System.getProperty("java.version"));
  558. logger.info("java.vm.vendor=[" + System.getProperty("java.vm.vendor") + "]");
  559. logger.info("java.version=[" + System.getProperty("java.version") + "]");
  560. printProviders();
  561. logger.info("================= SYS INFO end=====================");
  562. }
  563. public static void printProviders() {
  564. logger.info("Providers List:");
  565. Provider[] providers = Security.getProviders();
  566. for (int i = 0; i < providers.length; i++) {
  567. logger.info(i + 1 + "." + providers[i].getName());
  568. }
  569. }
  570. /**
  571. * 证书文件过滤器
  572. *
  573. */
  574. static class CerFilter implements FilenameFilter {
  575. public boolean isCer(String name) {
  576. if (name.toLowerCase().endsWith(".cer")) {
  577. return true;
  578. } else {
  579. return false;
  580. }
  581. }
  582. public boolean accept(File dir, String name) {
  583. return isCer(name);
  584. }
  585. }
  586. /**
  587. * <pre>
  588. * 从一个ThreadLocal中获取当前KeyStore中的CertId,
  589. * 如果获取失败则重新初始化这个KeyStore并存入ThreadLocal
  590. * </pre>>
  591. * @deprecated
  592. * @param certPath
  593. * @param certPwd
  594. * @return
  595. */
  596. public static String getCertIdByThreadLocal(String certPath, String certPwd) {
  597. // 初始化指定certPath和certPwd的签名证书容器
  598. initSignCert(certPath, certPwd);
  599. try {
  600. Enumeration<String> aliasenum = certKeyStoreLocal.get().aliases();
  601. String keyAlias = null;
  602. if (aliasenum.hasMoreElements()) {
  603. keyAlias = aliasenum.nextElement();
  604. }
  605. X509Certificate cert = (X509Certificate) certKeyStoreLocal.get()
  606. .getCertificate(keyAlias);
  607. return cert.getSerialNumber().toString();
  608. } catch (Exception e) {
  609. logger.error("获取签名证书的序列号失败", e);
  610. return "";
  611. }
  612. }
  613. public static String getCertIdByKeyStoreMap(String certPath, String certPwd) {
  614. if (!certKeyStoreMap.containsKey(certPath)) {
  615. // 缓存中未查询到,则加载RSA证书
  616. loadRsaCert(certPath, certPwd);
  617. }
  618. return getCertIdIdByStore(certKeyStoreMap.get(certPath));
  619. }
  620. private static String getCertIdIdByStore(KeyStore keyStore) {
  621. Enumeration<String> aliasenum = null;
  622. try {
  623. aliasenum = keyStore.aliases();
  624. String keyAlias = null;
  625. if (aliasenum.hasMoreElements()) {
  626. keyAlias = aliasenum.nextElement();
  627. }
  628. X509Certificate cert = (X509Certificate) keyStore
  629. .getCertificate(keyAlias);
  630. return cert.getSerialNumber().toString();
  631. } catch (KeyStoreException e) {
  632. logger.error("getCertIdIdByStore Error", e);
  633. return null;
  634. }
  635. }
  636. /**
  637. * 获取证书容器
  638. *
  639. * @return
  640. */
  641. public static Map<String, X509Certificate> getCertMap() {
  642. return certMap;
  643. }
  644. /**
  645. * 设置证书容器
  646. *
  647. * @param certMap
  648. */
  649. public static void setCertMap(Map<String, X509Certificate> certMap) {
  650. CertUtil.certMap = certMap;
  651. }
  652. /**
  653. * 使用模和指数生成RSA公钥 注意:此代码用了默认补位方式,为RSA/None/PKCS1Padding,不同JDK默认的补位方式可能不同
  654. *
  655. * @param modulus
  656. * 模
  657. * @param exponent
  658. * 指数
  659. * @return
  660. */
  661. public static PublicKey getPublicKey(String modulus, String exponent) {
  662. try {
  663. BigInteger b1 = new BigInteger(modulus);
  664. BigInteger b2 = new BigInteger(exponent);
  665. KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
  666. RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);
  667. return keyFactory.generatePublic(keySpec);
  668. } catch (Exception e) {
  669. logger.error("构造RSA公钥失败:",e);
  670. return null;
  671. }
  672. }
  673. /**
  674. * 使用模和指数的方式获取公钥对象
  675. *
  676. * @return
  677. */
  678. public static PublicKey getEncryptTrackCertPublicKey(String modulus,
  679. String exponent) {
  680. if (SDKUtil.isEmpty(modulus) || SDKUtil.isEmpty(exponent)) {
  681. logger.info("使用模和指数的方式获取公钥对象[modulus] OR [exponent] invalid");
  682. return null;
  683. }
  684. return getPublicKey(modulus, exponent);
  685. }
  686. }