Java读取硬件USBKey(简称UKEY)中的SSL证书信息,创建双向SSL认证上下文环境

最近项目中遇到了这样的需求,故记录下来,希望可以帮到需要的人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);
	}
}

注:上面的只是核心代码段,实际使用需要进行调整。


转载于:https://my.oschina.net/jsan/blog/647443

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基本的 C# 示例,演示如何读取 USB 密钥并获取证书和图像: ```csharp using System; using System.Security.Cryptography.X509Certificates; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; namespace UkeyTest { class Program { [DllImport("gclib.dll")] public static extern int GC_GetDllVersion(byte[] pVer); [DllImport("gclib.dll")] public static extern int GC_Init(int iType, int iPort, int iBaud); [DllImport("gclib.dll")] public static extern int GC_UnInit(); [DllImport("gclib.dll")] public static extern int GC_GetCardInfo(byte[] pCardInfo, int iInfoLen); static void Main(string[] args) { // 初始化 USB 密钥 int ret = GC_Init(0, 100, 115200); if (ret != 0) { Console.WriteLine("初始化 USB 密钥失败!Error Code: {0}", ret); return; } // 获取 USB 密钥证书 byte[] certBuf = new byte[4096]; ret = GC_GetCardInfo(certBuf, certBuf.Length); if (ret <= 0) { Console.WriteLine("获取 USB 密钥证书失败!Error Code: {0}", ret); GC_UnInit(); return; } X509Certificate2 cert = new X509Certificate2(certBuf); Console.WriteLine("证书主题:{0}", cert.Subject); Console.WriteLine("证书颁发者:{0}", cert.Issuer); Console.WriteLine("证书有效期:{0} - {1}", cert.NotBefore, cert.NotAfter); // 获取 USB 密钥图像 byte[] imgBuf = new byte[1024 * 1024]; ret = GC_GetCardInfo(imgBuf, imgBuf.Length); if (ret <= 0) { Console.WriteLine("获取 USB 密钥图像失败!Error Code: {0}", ret); GC_UnInit(); return; } Image img = Image.FromStream(new MemoryStream(imgBuf)); Console.WriteLine("图像大小:{0} x {1}", img.Width, img.Height); // 保存 USB 密钥图像到文件 img.Save("ukey_image.jpg", ImageFormat.Jpeg); // 关闭 USB 密钥 GC_UnInit(); } } } ``` 请注意,此示例代码使用的方法和函数来自于 `gclib.dll`,这是一个与 USB 密钥相关的第三方库。因此,在使用此代码之前,请确保您已正确安装了 `gclib.dll` 并将其添加到您的项目引用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值