USBKey 技术在 J2EE 项目中的应用

USBKey 技术和数字证书技术一样,也是数字签名的一种应用。我们知道,数字签名是非对称密钥加密技术与数字摘要技术的应用。所以归根结底使用 USBKey 还是用到非对称加密。

什么是 USBKey

USBKey 主要包含两块:加密芯片和带有安全存储的空间。

加密芯片可以实现 PKI 体系中使用的数据摘要,数据加解密和签名的各种算法,加解密算法在 USBKey 内进行,保证用户密钥不会出现在计算机内存中,从而杜绝了用户密钥被黑客截取的可能性。

带有安全存储的空间内部划分成数据存储区和密钥存储区,将软件的一些重要信息 (如序列号等) 保存在多功能锁中的数据存储区中,将进行加密用的密钥写在多功能锁中的密钥存储区中,密钥外界是不能获得的。

USBKey 初始化过程

  • 将密码算法程序烧制在 USBKey 的 ROM 中。

  • 通过产生公私密钥对的程序生成一对公私密钥,公钥保存在服务器端,供验签使用。

  • 私钥存储于 USBKey 密钥存储区,不允许外部访问。

  • 基于使用非对称加密技术以及密钥运算过程由加密芯片在 USBKey 内部完成,外界无法获取密钥。因此使用 USBKey 是安全的。

USBKey 应用步骤

  1. 产生一个随机字符串(这个字符串可以是服务器端传给页面,也可以是页面通过 JS 自己生成)

  2. 调用 USBKey 的签名方法对上面的随机字符串签名得到签名串(这一步一般需要安装 USBKey 厂商的 ActiveX 控件)

  3. 将随机字符串、签名串、用户名、密码等提交表单到后台

  4. 后台根据用户名密码判断用户,并得到用户的公钥(公钥是跟用户关联的,当然最简单的就是作为用户表的一个字段)。根据提交的随机字符串、签名串、公钥验签。

1
2
<!-- USBKey ActiveX 空间 不同厂商不一样 -->
<OBJECT id="OCX" style="display:none" classid="clsid:B33CED4C-53E0-4F76-B80C-CEAA6DE23551" VIEWASTEXT></OBJECT>
1
2
3
4
// 生成随机数并获得签名  
var randomNo = Math.round(Math.random() * 10000);
$('#__randomNo').val(randomNo);
$('#__key').val(ocx.SignMsg(randomNo));
1
2
3
4
5
6
7
8
9
10
11
12
// 验证签名
boolean b = KeyHelper.isValidKey(user.getPublickey(), sigenedUsbkey, randomNo);
if (!b) {
setResult(false, "验证用户 USBKEY 不通过!", request);
return mapping.findForward(LOGIN);
}
// 验证签名
public static boolean isValidKey(String userPubKey, String key, String randomNo) throws Exception {
JSignVerify signverify = new JSignVerify();
signverify.ReadRawPublicKeyFromBigInt(userPubKey);
return signverify.VerifyMemorySHA1(randomNo.getBytes(), Base16.hexStrToBytes(key));
}