“数字证书”这个名词相信很多人听过,但并不了解,“ejbca”可能很多人都没有听过
数字证书(Certificate),就是互联网通信过程中标志通信各方身份的一个文件,可以理解为“网络身份证”,主要目的是验证身份
ejbca,是一个CA(Certificate Authority)系统软件,CA是数字证书认证中心的简称,主要功能是管理数字证书,包括证书的颁发、销毁、更新等,ejbca实现了CA规范,因此可以用来管理数字证书
接下来,笔者将按照ejbca安装、使用、数字证书使用、web service接口、nginx代理顺序逐步介绍一个独立ca系统完整的建立与使用过程
centos安装ejbca-community-6.3.1.1
ejbca安装过程算比较复杂了,本文以centos 6.5系统为例介绍安装过程,其他linux可以参考,windows下的安装过程几乎相同,安装过程使用是ejbca community 6.3.1.1(社区版),安装过程请严格按照以下步骤,不然很容易出错!
1、安装基础环境
安装ejbca需要jdk-1.7以上、ant构建工具、可用的mysql数据库、jboss-7.1.1,其中jdk、ant、mysql安装配置过程参考http://www.cnblogs.com/ywlaker/p/6129872.html,如果已经安装过这些,可以忽略,直接进入以下步骤
2、安装启动jboss
从jboss官方网站下载jboss安装包:jboss-as-7.1.1.Final.tar.gz,解压并配置环境变量
tar xvf jboss-as-7.1.1.Final.tar.gz -C /usr/java vi /etc/profile
追加内容
#jboss conf export JBOSS_HOME=/usr/java/jboss-as-7.1.1.Final
使配置立即生效
source /etc/profile
启动jboss,注意最后的&符号,待启动完成再运行“exit”
sh /usr/java/jboss-as-7.1.1.Final/bin/standalone.sh & exit
这样jboss就运行在后台了,以下命令查看jboss进程并关闭
ps -ef|grep jboss kill -9 进程号
3、配置jboss的mysql数据源
创建目录,然后在该目录下创建module.xml
mkdir -p /usr/java/jboss-as-7.1.1.Final/modules/com/mysql/main cd /usr/java/jboss-as-7.1.1.Final/modules/com/mysql/main vi module.xml
module.xml内容如下
<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.0" name="com.mysql"> <resources> <resource-root path="mysql-connector-java-5.1.27.jar"/> </resources> <dependencies> <module name="javax.api"/> <module name="javax.transaction.api"/> </dependencies> </module>
下载mysql的驱动包mysql-connector-java-5.1.27.jar,放在/usr/file目录,然后拷贝到当前目录
cp /usr/file/mysql-connector-java-5.1.27.jar ./
打开新的shell窗口,运行
sh /usr/java/jboss-as-7.1.1.Final/bin/jboss-cli.sh -c
如果是“disconnect”状态,先输入“connect”,多回车几次后,运行下面命令
/subsystem=datasources/jdbc-driver=com.mysql.jdbc.Driver:add(driver-name=com.mysql.jdbc.Driver,driver-class-name=com.mysql.jdbc.Driver,driver-module-name=com.mysql,driver-xa-datasource-class-name=com.mysql.jdbc.jdbc.jdbc2.optional.MysqlXADataSource) :reload
4、安装配置ejbca
从ejbca官方网站下载ejbca安装包:ejbca_ce_6_3_1_1.zip,放在/usr/file目录,解压,准备修改配置
unzip /usr/file/ejbca_ce_6_3_1_1.zip -d /usr/java cd /usr/java mv ejbca_ce_6_3_1_1 ejbca-ce-6.3.1.1 cd /usr/java/ejbca-ce-6.3.1.1/conf/
1、修改ejbca.properties
mv ejbca.properties.sample ejbca.properties vi ejbca.properties
修改如下内容
appserver.home=/usr/java/jboss-as-7.1.1.Final appserver.type=jboss
2、修改database.properties
mv database.properties.sample database.properties vi database.properties
修改如下内容
# dataSource datasource.jndi-name=jboss/datasources/MySqlDS # mysql info database.name=mysql database.url=jdbc:mysql://127.0.0.1:3306/ejbca?characterEncoding=UTF-8 database.driver=com.mysql.jdbc.Driver database.username=root database.password=root
3、修改install.properties
mv install.properties.sample install.properties vi install.properties
修改如下内容
#设置ca名称 ca.name=test #设置ca信息 ca.dn=CN=test,O=test,C=cn
4、修改cesecore.properties、jaxws.properties,不需要修改内容
mv cesecore.properties.sample cesecore.properties mv jaxws.properties.sample jaxws.properties
5、修改web.properties
mv web.properties.sample web.properties vi web.properties
修改如下内容
#密码最好6位 superadmin.password=123456 superadmin.cn=superadmin httpsserver.hostname=ca.test.com httpsserver.dn=CN=${httpsserver.hostname},O=test,C=cn
5、部署ejbca到jboss
首先,在配置的mysql中创建“ejbca”数据库,编码“utf-8”,然后正式用ant构建ejbca并安装到jboss
cd /usr/java/ejbca-ce-6.3.1.1 ant clean deploy ant install ant deploy-keystore
deploy用ant部署,install生成证书,deploy-keystore将证书部署到jboss,前两步所需时间较长,过程中如需输入,请直接回车
6、配置jboss开启https
打开新的shell窗口,运行
sh /usr/java/jboss-as-7.1.1.Final/bin/jboss-cli.sh -c
如果是“disconnect”状态,运行“connect”,多回车几次,准备运行下面4部分配置
第一部分(配置任意主机可访问)
/interface=http:add(inet-address="0.0.0.0") /interface=httpspub:add(inet-address="0.0.0.0") /interface=httpspriv:add(inet-address="0.0.0.0") /socket-binding-group=standard-sockets/socket-binding=http:add(port="8080",interface="http") /subsystem=undertow/server=default-server/http-listener=http:add(socket-binding=http) /subsystem=undertow/server=default-server/http-listener=http:write-attribute(name=redirect-socket, value="httpspriv") :reload
第二部分(配置证书)
/core-service=management/security-realm=SSLRealm:add() /core-service=management/security-realm=SSLRealm/server-identity=ssl:add(keystore-path="${jboss.server.config.dir}/keystore/keystore.jks", keystore-password="serverpwd", alias="prod-ica1") /core-service=management/security-realm=SSLRealm/authentication=truststore:add(keystore-path="${jboss.server.config.dir}/keystore/truststore.jks", keystore-password="changeit") /socket-binding-group=standard-sockets/socket-binding=httpspriv:add(port="8443",interface="httpspriv") /socket-binding-group=standard-sockets/socket-binding=httpspub:add(port="8442", interface="httpspub") :reload
第三部分(配置ssl)
/subsystem=undertow/server=default-server/https-listener=httpspriv:add(socket-binding=httpspriv, security-realm="SSLRealm", verify-client=REQUIRED) /subsystem=undertow/server=default-server/https-listener=httpspub:add(socket-binding=httpspub, security-realm="SSLRealm") :reload
第四部分(配置web service)
/system-property=org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH:add(value=true) /system-property=org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH:add(value=true) /system-property=org.apache.catalina.connector.URI_ENCODING:add(value="UTF-8") /system-property=org.apache.catalina.connector.USE_BODY_ENCODING_FOR_QUERY_STRING:add(value=true) /subsystem=webservices:write-attribute(name=wsdl-host, value=jbossws.undefined.host) /subsystem=webservices:write-attribute(name=modify-wsdl-address, value=true) :reload
使用ejbca管理数字证书
ejbca安装完成后,我们就可以使用它管理数字证书了,假设安装ejbca的服务器地址为:172.17.210.124,我们在windows系统下先配置一个hosts,编辑“C:\Windows\System32\drivers\etc”目录下的hosts文件,加入一行
172.17.210.124 ca.test.com
然后拷贝ejbca服务器“/usr/java/ejbca-ce-6.3.1.1/p12/”目录下的superadmin.p12文件到windows系统,双击该文件开始安装,默认密码是“ejbca”,如果配置过程中修改过,请使用修改过的密码如“123456”
ejbca系统提供了两个界面
管理员界面(需要证书,使用刚才安装的superadmin证书)
https://ca.test.com:8443/ejbca/adminweb/
用户界面
http://ca.test.com:8080/ejbca/
弄好了超级管理员证书之后,我们开始管理数字证书吧!
1、用户注册
数字证书是身份认证的载体,身份认证的对象就是“用户”,数字证书包含“用户”的基本信息,就想身份证包含了你的姓名等基本信息一样,注册过程即是你想ejbca提交个人基本信息
ejbca管理员界面中,打开“RA Functions”—“Add End Entity”菜单,填写以下“Required”列打勾的项。
用户模板选择“EMPTY”
输入用户名与密码
Common name,如果是服务器用证书,这里请填写域名
填写证书信息,证书模板选择“ENDUSER”,CA选择“dev”,Token选择“P12 file”
最后点击“Add”按钮注册
2、下载证书
注册完用户,自然迫不及待要弄到一个证书了,在ejbca用户界面中,打开“Enroll”—“Create Browser Certificate”菜单
输入用户名和密码,点击“OK”按钮,进入下面的页面
“Key length”选择“2048 bits”;“Certificate profile”选择“ENDUSER”,点击“Enroll”按钮下载证书
3、吊销证书
管理员发现用户证书被人盗用了,好办,吊销它
ejbca管理员界面中,打开“RA Functions”—“Search End Entities”菜单。“Search end entities with status”处下拉框选择“All”,点击右边的“Search”按钮查看用户信息(下图省略其他列)
勾选需要吊销的用户,点击表格下方的“Revoke Selected”按钮,吊销用户
4、更新证书
用户上次申请的证书到期了,要更换新的证书
ejbca管理员界面中,打开“RA Functions”—“Search End Entities”菜单。“Search end entities with status”处下拉框选择“All”,点击右边的“Search”按钮查看用户信息(下图省略其他列)
点击需要更新证书用户的最右边列中的“Edit End Entity”超链接,编辑用户
设置“Status”为“New”,点击右边的“Save”按钮。然后输入新密码,其他项保持不变,点击页面最下方的“Save”按钮保存设置
5、根证书
ejbca作为一个CA,有它自己的根证书
ejbca用户界面中,打开“Retrieve”—“Fetch CA Certificates”菜单,可以下载不同格式的根证书
6、申请tomcat服务器证书
以上方式可以管理普通用户用的浏览器证书,格式为p12,tomcat服务器用的证书格式为jks,怎么申请呢?
用户注册时,证书模板选择“SERVER”,CA选择“dev”,Token选择“JKS file”,其他项的值不变
下载证书时,在ejbca用户界面中,打开“Enroll”—“Create Keystore”菜单,输入用户名与密码,进入下面的页面
“Key length”选择“2048 bits”;“Certificate profile”选择“SERVER”,点击“Enroll”按钮下载证书
其他服务器证书格式大同小异,相信你可以摸索出来!
使用web service构建自己的CA系统
ejbca系统虽然安装好了,也可以管理数字证书,但是,我们所有的操作都在ejbca提供的界面中执行,先不说全部是英文,单单它里面很多配置项就让人眼花缭乱,很多配置项要么是固定的,要么是不需要的,因此,最合理的做法是在ejbca之上构建一个中间层,用户访问中间层提供的证书管理服务,中间层的服务则使用ejbca实现,正好ejbca提供了完整的web service接口
中间层只需要提供数字证书的注册、下载、吊销、更新即可,更多的功能当然也可以实现,看具体需求了,下面介绍这个中间层的基本实现过程
1、superadmin.jks证书
ejbca提供的web service接口需要证书认证,官方源码给出的例子中使用的就是superadmin超级管理员的证书,但格式是jks,因此我们需要弄到superadmin.jks证书,通过工具转换是可以的,但ejbca可以直接生成
对superadmin用户执行更新操作,保存之前,修改下面项的值为“JKS file”
按照下载普通用户证书的步骤下载superadmin的jks格式证书
2、初始化web service连接
有了superadmin.jks证书,我们就可以用它来连接web service服务了,但是,必须将web service所需的jar包添加到工程中,这些jar包是下面两个目录下的所有jar
/usr/java/ejbca-ce-6.3.1.1/dist/ejbca-ws-cli/lib /usr/java/ejbca-ce-6.3.1.1/dist/ejbca-ws-cli
然后在代码中初始化web service连接
public void init() { if (!new File(certPath).exists()) return; CryptoProviderTools.installBCProvider(); System.setProperty("javax.net.ssl.trustStore", "d:/superadmin.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "123456"); System.setProperty("javax.net.ssl.keyStore", "d:/superadmin.jks"); System.setProperty("javax.net.ssl.keyStorePassword", "123456"); QName qname = new QName("http://ws.protocol.core.ejbca.org/", "EjbcaWSService"); try { EjbcaWSService service = new EjbcaWSService(new URL("https://ca.test.com:8443/ejbca/ejbcaws/ejbcaws?wsdl"), qname); EjbcaWS ejbcaWS = service.getEjbcaWSPort(); } catch (Exception e) { } }
注意:连接地址只能是域名,这个域名是安装ejbca时为ejbca服务器指定的,所以连接ejbca提供的web service接口服务的机器要配置hosts
172.17.210.124 ca.test.com
初始化的目的是拿到EjbcaWS对象的实例,接下来的数字证书的注册、下载等服务均基于它
3、实现数字证书管理服务
查看用户是否已经注册
private boolean isExist(String username) throws Exception { UserMatch usermatch = new UserMatch(); usermatch.setMatchwith(UserMatch.MATCH_WITH_USERNAME); usermatch.setMatchtype(UserMatch.MATCH_TYPE_EQUALS); usermatch.setMatchvalue(username); try { List<UserDataVOWS> users = ejbcaWS.findUser(usermatch); if (users != null && users.size() > 0) { return true; } else { return false; } } catch (Exception e) { throw new Exception("检查用户 " + username() + " 是否存在时出错:" + e.getMessage()); } }
用户注册与更新,用的都是editUser()方法,因此要先判断是否存在
public void editUser() throws Exception { UserDataVOWS userData = new UserDataVOWS(); userData.setUsername("testname");//用户名 userData.setPassword("123456");//密码 userData.setClearPwd(false);//默认 userData.setSubjectDN("CN=" + "testname" + ",OU=" + "testou" + ",O=" + "testo" + ",C=cn" + ",telephoneNumber=" + "1234567890" );//设置唯一甄别名 String pattern = "yyyy-MM-dd HH:mm:ssZZ"; // ISO 8601标准时间格式 userData.setStartTime(DateFormatUtils.format(new Date(),pattern));//证书有效起始日期 userData.setEndTime(DateFormatUtils.format(DateUtils.addDays(new Date(), 100), pattern));//结束日期 userData.setCaName("test");//ca名称,ejbca的名称 userData.setSubjectAltName(null); userData.setEmail("[email protected]");//邮件地址 userData.setStatus(UserDataVOWS.STATUS_NEW);//状态为new userData.setTokenType(UserDataVOWS.TOKEN_TYPE_P12);//设置p12格式证书 userData.setEndEntityProfileName("user");//终端实体模板 userData.setCertificateProfileName("user");//证书模板 try { ejbcaWS.editUser(userData); } catch (Exception e) { throw new Exception(e.getMessage()); } }
代码中有几处值得注意的,终端实体模板“user”和证书模板“user”需要在ejbca管理员界面中配置,并且终端实体模板“user”中要配置开启“SubjectDN”的属性如CN、OU、O、C、telephoneNumber等,还要允许修改startTime和endTime
吊销证书
public void revoke(String username) throws ServiceException { try { ejbcaWS.revokeUser(username, RevokedCertInfo.REVOCATION_REASON_UNSPECIFIED, false); } catch (Exception e) { } }
创建证书
private void createCert(String username, String password, String path) throws Exception { FileOutputStream fileOutputStream = null; try { // 创建证书文件 KeyStore ksenv = ejbcaWS.pkcs12Req(username, password, null, "2048", AlgorithmConstants.KEYALGORITHM_RSA); java.security.KeyStore ks = KeyStoreHelper.getKeyStore(ksenv.getKeystoreData(), "PKCS12", password); fileOutputStream = new FileOutputStream(path + File.separator + username + ".p12"); ks.store(fileOutputStream, password.toCharArray()); // 创建密码文件 File pwdFile = new File(path + File.separator + username + ".pwd"); pwdFile.createNewFile(); BufferedWriter out = new BufferedWriter(new FileWriter(pwdFile)); out.write(password); out.flush(); out.close(); } catch (Exception e) { throw new Exception("用户 " + username + " 证书创建失败:" + e.getMessage()); } finally { if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (IOException e) { } } } }
证书创建在服务器上,用户调用下载证书的接口服务,应该返回一个下载地址,这里介绍用nginx作为文件下载服务器,参考http://www.cnblogs.com/ywlaker/p/6129872.html一文介绍的关于nginx的部分
到此为止,ejbca构建的ca系统已经完成,当然,上述只是核心代码,怎么运行、部署就不介绍了,下面简单介绍https基本原理与数字证书的使用