您的位置:首页 > 编程语言 > Java开发

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)。

直接上代码段示例:

// 厂商提供的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);
}
}


注:上面的只是核心代码段,实际使用需要进行调整。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: