Java读取硬件USBKey(简称UKEY)中的SSL证书信息,创建双向SSL认证上下文环境
2016-06-07 10:18
2131 查看
摘要: 使用Java读取硬件USBKey(简称UKEY)中的SSL证书信息,创建双向SSL认证上下文环境,进行双向HTTPS服务请求调用。
最近项目中遇到了这样的需求,故记录下来,希望可以帮到需要的人O(∩_∩)O~
以下以 Linux 环境为基础:
读取硬件 UKEY 的SSL证书信息,需要硬件厂商提供:UKEY型号名称、驱动文件(类似pkcs11.so)。
直接上代码段示例:
注:上面的只是核心代码段,实际使用需要进行调整。
最近项目中遇到了这样的需求,故记录下来,希望可以帮到需要的人O(∩_∩)O~
以下以 Linux 环境为基础:
读取硬件 UKEY 的SSL证书信息,需要硬件厂商提供:UKEY型号名称、驱动文件(类似pkcs11.so)。
直接上代码段示例:
// 厂商提供的UKEY型号名称 static final String UKEY_PROVIDER = "xxx"; // UKEY驱动lib库文件 static final String UKEY_LIB = "/usr/local/lib/xx pkcs11.so"; // UKEY的PIN码 static final Strign UKEY_PIN = "123456"; // 1. 通过上面的UKEY硬件信息创建 java.security.Provider static void initProvider() { // 固定格式的配置信息 // 例如:cfg = "name = OpenSC\n" // + "library = /usr/lib/opensc-pkcs11.so\n"; String ukeyCfg = "name = %s\nlibrary = %s\n"; ukeyCfg = String.format(ukeyCfg, UKEY_PROVIDER, UKEY_LIB); // 方式1 //java.security.Provider provider = new sun.security.pkcs11.SunPKCS11(new ByteArrayInputStream(ukeyCfg.getBytes("UTF-8"))); // 方式2 Class sunPkcs11 = Class.forName("sun.security.pkcs11.SunPKCS11"); Constructor pkcs11Constr = sunPkcs11.getConstructor(InputStream.class); java.security.Provider provider = (Provider) pkcs11Constr.newInstance(new ByteArrayInputStream(ukeyCfg.getBytes("UTF-8"))); // 加载 Provider Security.addProvider(provider); } // 2. 通过 PIN 码获取秘钥KeyStore static KeyStore getKeyStore() { // 可以通过上面创建的 Provider,生成来自指定提供者的KeyStore信息 // KeyStore ks = KeyStore.getInstance("PKCS11", java.security.Provider); // 也可以这样省略 java.security.Provider 参数 // 如果不指定 Provider,则从首选Provider开始遍历已经注册的安全提供者, // 找到第一个支持指定类型的Provider来生成 KeyStore KeyStore ks = KeyStore.getInstance("PKCS11"); ks.load(null, UKEY_PIN.toCharArray()); return ks; } /** * 3. 创建 HttpsConnection双向认证上下文环境 * * @param keystore 步骤2中创建的 keystore * @param alias 证书别名,可以为空 * @param pinPassword UKEY要求输入的PIN码 */ static void loadSSLContext(KeyStore keystore, String alias, String pinPassword) { // 实例化信任库,make a naive trust manager that does not check cert validity TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { // ignore } public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { // ignore } }}; KeyManager[] managers; if(alias != null && alias.trim().length() > 0) { managers = new KeyManager[] { new AliasKeyManager(keystore, alias, pinPassword) }; } else { // 初始化密钥工厂 create a KeyManagerFactory from the keystore KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(keystore, pinPassword.toCharArray()); managers = kmf.getKeyManagers(); } // 实例化SSL上下文 install the keymanager factory, and the trust manager SSLContext sc = SSLContext.getInstance("SSL"); // 初始化SSL上下文 sc.init(managers, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); // prevent checking the hostname for spoofing HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); } /** * 密钥管理器【KeyManager】中证书别名的处理 */ static class AliasKeyManager implements X509KeyManager { private KeyStore _ks; private String _alias; private String _password; public AliasKeyManager(KeyStore ks, String alias, String password) { this._ks = ks; this._alias = alias; this._password = password; } public String chooseClientAlias(String[] str, Principal[] principal, Socket socket) { return this._alias; } public String chooseServerAlias(String str, Principal[] principal, Socket socket) { return this._alias; } public X509Certificate[] getCertificateChain(String alias) { try { return (X509Certificate[]) _ks.getCertificateChain(alias); } catch (Exception e) { e.printStackTrace(); return null; } } public String[] getClientAliases(String str, Principal[] principal) { return new String[] { this._alias }; } public PrivateKey getPrivateKey(String alias) { try { return (PrivateKey) this._ks.getKey(alias, this._password == null ? null : this._password.toCharArray()); } catch (Exception e) { e.printStackTrace(); return null; } } public String[] getServerAliases(String str, Principal[] principal) { return new String[] { this._alias }; } } // 4. demo static void test() { HttpsURLConnection urlCon = (HttpsURLConnection) (new URL("https://your url")).openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader(urlCon.getInputStream())); String line = null; while ((line = in.readLine()) != null) { System.out.println(line); } in.close(); } // 可选:打印 KeyStore中的信息 private void printKeyStoreInfo(KeyStore keystore) { System.out.println("Provider : " + keystore.getProvider().getName()); System.out.println("Type : " + keystore.getType()); System.out.println("Size : " + keystore.size()); Enumeration en = keystore.aliases(); while (en.hasMoreElements()) { String alias = (String) en.nextElement(); System.out.println("Alias: " + alias); X509Certificate cert = (X509Certificate) keystore.getCertificate(alias); System.out.println("Certificate: " + cert); PrivateKey privateKey = (PrivateKey) keystore.getKey(alias, null); System.out.println("Private key: " + privateKey); } }
注:上面的只是核心代码段,实际使用需要进行调整。
相关文章推荐
- jsp页面中实现时间相减,并且在最近添加的新闻后右上角添加标记(涉及struts2标签和jquey)
- 使用IntelliJ IDEA 14和Maven创建java web项目
- java之抽象概念
- Java正则表达式pattern和matches
- JAVA集合框架学习总结
- java 获取mac地址
- springmvc mybatis maven 整合 事例
- java的if else语句入门
- Java 写文件:FileOutputStream
- Java concurrency – CountDownLatch Example
- java之自动装箱拆箱
- Java学习之InputStream中read()与read(byte[] b)
- js生成日志信息及实现java直接调用flume
- Java链接elasticsearch的api
- Struts2基于注解配置Action
- 深入Java关键字null
- java异常处理详解
- Java初学者都必须理解的六大问题
- Spring MVC学习总结(5)——SpringMVC项目关于安全的一些配置与实现方式
- Java多线程和线程池