• 热门专题

基于ejbca community 6.3.1.1构建独立ca系统管理数字证书

作者:凌承一  发布日期:2016-12-05 20:46:51
Tag标签:数字证书  系统  
  •   “数字证书”这个名词相信很多人听过,但并不了解,“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:WindowsSystem32driversetc”目录下的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('test@test.com');//邮件地址
    	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基本原理与数字证书的使用

    https基本原理与数字证书的使用

      首先,介绍下密码学的基本知识,我们从下面的加密通信模型开始

      我向朋友发送一条消息“有时间一起吃饭吗”,实际在网络中传输的是加密后的数据,而不是原文,只是加密和解密过程对我和朋友是透明的

    1、对称与非对称加密

      上述通信过程中,如果加密与解密使用相同的密钥,称为对称加密,如果使用不同的密钥,称为非对称加密

      对称加密的特点是速度快,可加密的数据量大;非对称加密的特点是速度慢,因此只用来加密少量数据,但极难破解

      非对称加密过程中使用的两个不同的密钥,一个称为“私钥”,一个称为“公钥”,它们一一对应,称为“密钥对”,“公钥”可以给任何人使用,但“私钥”必须自己保持,一旦“私钥”泄露,这个密钥对就应该被抛弃

      密钥对有两个非常重要的特点:1、“私钥”可以导出“公钥”,但“公钥”无法导出“私钥”;2、经“私钥”加密的内容只能由“公钥”解密,经“公钥”加密的内容也只能由“私钥”解密。

      这两个特点有两个重要用途:1、“私钥”持有者用“私钥”加密内容,发送给“公钥”持有者解密,验证“私钥”持有者的身份。因为“公钥”能解密的内容,只能是由“私钥”加密的;2、“公钥”持有者用“公钥”加密内容,发送给“私钥”持有者解密,保证内容安全。因为只有“私钥”能解密,即使内容被截获,截获者也无法知道内容是什么

    2、数字证书

      数字证书是一个文件,包含了使用者的身份信息、以及权威机构(CA)的数字签名,就向我们的居民身份证一样,数字证书是“网络身份证”,用于验证互联网上证书持有者的身份

      颁发数字证书的机构叫CA,全世界只有少数权威的CA,因为颁发出去的证书它们是要负法律责任的,所以向它们申请证书也要缴费,我们自己搭建的ejbca颁发的证书只适合在企业内部使用,这个CA是没有权利向互联网上其他商业公司颁发证书的

      有了数字证书,只要配置服务开启https就可以使用数字证书了

      https对于数字证书的认证包括“单向认证”与“双向认证”,“单向认证”只由客户端验证服务器,“双向认证”则两者相互验证,只要验证不通过,通信就自动中断,下面介绍通信的流程以及如何在tomcat中配置

    3、https单向认证

      “单向认证”的两个实体

      “单向认证”的流程如下图

      简要说明如下

    客户端访问服务器
    服务器响应客户端,发送服务器证书给客户端
    客户端查询“受信任根证书颁发机构”,验证服务器证书
    客户端验证完服务器证书,生成“密钥对”及会话密钥,与服务器协商会话密钥
    会话密钥协商完成,开始安全加密通信
    

      tomcat开启https单向认证的配置

    <Connector port='8443' protocol='org.apache.coyote.http11.Http11Protocol'
        maxThreads='150' SSLEnabled='true' scheme='https' secure='true'
        clientAuth='false' sslProtocol='TLS'
        keystoreFile='D:	omcat.jks' keystorePass='123456' />

    4、https双向认证

      “双向认证”的两个实体

      “双向认证”的流程如下图

      简要说明如下

    客户端访问服务器
    服务器响应客户端,发送服务器证书给客户端
    客户端查询“受信任根证书颁发机构”,验证服务器证书
    验证完服务器证书,客户端发送客户端证书给服务器
    服务器查询“信任库”或通过证书链,验证客户端证书
    客户端与服务器协商会话密钥加密方案
    客户端与服务器协商会话密钥
    会话密钥协商完成,开始安全加密通信
    

      tomcat开启https双向认证的配置

    <Connector port='8443' protocol='org.apache.coyote.http11.Http11Protocol'
        maxThreads='150' SSLEnabled='true' scheme='https' secure='true'
        clientAuth='true' sslProtocol='TLS'
        keystoreFile='D:	omcat.jks' keystorePass='123456'
        truststoreFile='D:	omcat.jks' truststorePass='123456'/>
About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规