首页 > 代码库 > 基于ejbca community 6.3.1.1构建独立ca系统管理数字证书

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

  “数字证书”这个名词相信很多人听过,但并不了解,“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="http://www.mamicode.com/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=http://www.mamicode.com/true)"UTF-8")
/system-property=org.apache.catalina.connector.USE_BODY_ENCODING_FOR_QUERY_STRING:add(value=http://www.mamicode.com/true)>

使用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 = http://www.mamicode.com/new UserDataVOWS();"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基本原理与数字证书的使用

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