注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

隐龙 为了一生的信念

今日默默沉于水,他日飞腾在九天...

 
 
 

日志

 
 

自制中文数字证书  

2012-07-27 16:33:19|  分类: CAS/SSO |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
当前,数字证书应用已深入到日常生活的诸多活动中。而通过了解在Linux下制作数字证书的过程可以详细了解数字证书的实质,亦可尝试在内部系统中免费使用中文数字证书。

数字证书采用PKI(Public Key Infrastructure)公开密钥基础架构技术,利用一对互相匹配的密钥进行加密和解密。但在内部系统应用中,不需要专门CA(认证授权中心)的认证证书,可自己建立认证服务器。可以用Windows 2003 Server证书颁发机构作为CA,用Java制作中文申请后向Windows 2003 Server证书颁发机构CA申请证书,这样就可以得到简体中文数字证书了。本文讨论在简体中文Linux系统中的Tomcat Web服务器上制作数字证书的方法。

证书的产生方法

在Linux下做CA,必须安装openssl,该软件的最新版本可以从www.openssl.org下载。不过,即使直到最新版本,openssl输入简体中文信息后产生的证书也会显示为乱码。还好,有两个办法可以解决这个问题: 一是修改openssl源程序; 另一个是用UTF-8编码进行处理。由于前一种方法比较复杂,本文主要讨论后一种方法。在输入中文字符时,openssl可以正确处理UTF-8的字符编码,不能处理简体中文的gb2312编码。于是可将简体中文的用户信息输入到配置文件中,再转换为UTF-8编码,生成证书申请时使用配置文件的缺省信息,即可产生正确显示中文的证书。其方法如下:

1.假设配置文件为openssl.cnf,编辑修改如下内容:

string_mask=utf8only

countryName_default=CN stateOrProvinceName_default=省份

localityName_default=城市 O.organizationName_default=部门

organizationalUnitName_default=单位 commonName_default=名字

2.用iconv命令将文件格式转换为UTF-8编码:

iconv -f gbk -t utf-8 openssl.cnf > openssl_utf8.cnf

3.用openssl生成证书签名请求时,加上”-utf8”和将配置文件指定为openssl_utf8.cnf:

openssl req -utf8 -config openssl_utf8.cnf -new -out req.csr

除了输入密码,其他的一律选择回车,使用显示为乱码的缺省值,就可产生包含正确中文信息的证书申请文件req.csr,这样的申请方式可用于CA和客户证书的申请。Tomcat服务器证书需要生成keystore文件,用Java工具keytool命令生成,安装简体中文版本的Java,可正确生成简体中文的证书申请。

证书生成步骤和使用

1. 生成自签名认证的CA证书ca-cert.p12。其中在生成CA申请时,CA的中文信息要使用上述的UTF-8中文编码格式。

openssl req -config ca/openssl_ca_utf8.cnf -new -out ca/ca-req.csr -key ca/ca-key.pem

2. 生成服务器证书。Tomcat Web服务器使用keystore文件,内含CA根证书和服务器证书,需要使用Java的keytool工具生成keystore文件。不过如果使用dname选项直接在命令行中写入,可减少中文输入法的麻烦。

keytool -genkey -alias tomcat -dname "CN=域名,OU=部门,O=组织,L=城市,S=省份 ,C=CN" -validity 365  -keyalg RSA -keysize 1024 -keystore server/server-keystore

最后将CA证书和生成的服务器证书用keytool命令导入server-keystore文件。

3. 生成客户证书client-cert.p12。在生成客户证书申请时,要为每个客户的中文信息生成UTF-8中文编码文件:

openssl req -config client/openssl_cl_utf8.cnf -new -out client/client-req.csr -key client/client-key.pem

Tomcat使用keystore文件存放证书,并在server.xml设置安全连接以使用证书,server.xml配置例子如下,假设使用8443端口支持https:

<Connector port="8443" …”scheme="https" keystoreFile="/server-keystore"  truststoreFile="/server-keystore" …/>

将ca-cert.p12和client-cert.p12导入客户浏览器或USBKey中,即可使用证书,用“https://域名: 8443 URL”即可访问服务器。

JSP中文编码转换

从以上过程得到的服务器证书是简体中文编码的,而CA和客户证书使用的是UTF-8编码。在显示和使用中都没有问题。若应用中服务器需要处理客户证书的信息,JSP可使用X509Certificate对象获得证书信息。如果要显示该客户证书信息,则需要使用UTF-8编码转换,而且页面设置为UTF-8编码:

String subdn_utf8 = new String(subdn.getBytes("ISO8859_1"), "UTF-8");

在国内环境中,一般需要简体中文gb2312(gbk)编码,不但需要显示中文,而且还需要处理简体中文编码信息。这就要求在jsp中将获取的UTF-8编码转换为gb2312编码。但问题是Java JDK本身没有提供编码转换的类,所有和编码有关的类都在sun.io.*和Java.nio.charset.*中,而自己编程转换代码又比较麻烦。

但是,JDK隐藏了一个私有类java.lang.StringCoding可实现编码转换。需要做的是复制java.lang.StringCoding源程序,在自己的项目中建立一个StringCoding类,将需要部分改为public,即可利用StringCoding的函数实现代码转换。步骤如下:

首先,在自己项目文件创建一个类StringCoding.java,拷贝源程序,并将类定义、构造函数、编码转换要用到的编码、解码函数改为“public”属性。

public static char[] decode(String charsetName, byte[] ba, int off, int len)

public static byte[] encode(String charsetName, char[] ca, int off, int len)

然后,在jsp应用程序中import StringCoding类,先获取UTF-8编码字节流,通过一系列编解码操作得到简体中文gb2312编码字符串。要点是在UTF-8字符数组下解码为简体中文字节数组才能正确转换代码。

String subdn=cert.getSubjectDN().toString();

byte[] byteutf8 = subdn.getBytes("iso8859_1");

char[] charutf8 = StringCoding.decode("utf-8",byteutf8,0,byteutf8.length);

byte[] bytegb = StringCoding.encode("gb2312",charutf8,0,charutf8.length);

String subdn_gb=new String(bytegb,"gb2312");

  评论这张
 
阅读(1152)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018