EJBCA使用之注册用户及创建证书

 http://blog.csdn.net/xanxus46/article/details/9103031
分类: ejbca   199人阅读  评论(0)  收藏  举报

研究ejbca源码快一个月了,从openipmp中的老版ejbca到最新的4.0.15,感觉看别人代码实在太痛苦了,而且之前自己对ejb并不是很熟悉,还必须自己重新学了一点基本的ejb知识。

我最开始是研究openipmp的,里面自带就有ejbca的jar包,所以一开始我看openipmp怎么调用ejbca就行,但是由于openipmp实在太老了,它使用的ejbca是遵守ejb2.1标准的尴尬,调用起来实在太复杂太麻烦了,所以经过一周后我彻底放弃它,重新看最新版的ejbca。

最新版的ejbca可以从官网下,官网下的包括java源码、jsp和一堆云里雾里的文档。但注意官网下的java源码并不是一个完整eclipse工程,我们需要修改源码的话,还是用svn检出eclipse工程的源码比较好。svn检出地址可以从http://ejbca.org/repository.html找到,是https://svn.cesecore.eu/svn/ejbca/branches/Branch_4_0/ejbca

检出完ejbca后,我们可以参考维基上关于ejbca的api http://wiki.ejbca.org/developers#toc6,我们首先导入工程,然后会发现有编译错误,因为工程使用了JBOSS5_HOME类变量,我们需要添加该变量,步骤是Window->Preferences->Java->Build Path->Classpath,指向jboss的根目录。设置完这个后还是不行,我们要使用ant命令编译得到一些必需的类,就在ejbca的根目录下使用ant,或者使用eclipse集成的ant。(注意,千万不要在windows X64上使用ejbca,因为windows X64的jdk缺少一个库,好像是sun的一个关于security的库,而ejbca必需这个库)。

做完以上步骤后,应该就没有问题了,我们现在就需要做最痛苦的事情——读代码。还好,ejbca的注释还是比较详尽的,而且都是javadoc注释,在eclipse查看很方便。好了,废话不多说,马上进入正题,使用ejbca注册新用户并且为用户导出证书。

注册新用户:ejbca使用方式有两种:web和命令行。web很简单,网上很多教程,这里主要介绍命令行方式。我们可以找到modules/ejbca-ejb-cli/src这个包里面都是使用命令行方式操作ejbca,而注册新用户是属于ra的操作,我们需要看org.ejbca.ui.cli.ra.RaAddUserCommand类,它的execute方法就是添加一个用户,那我们只需要调用该方法就添加用户,实在不明白这么好用的方法,ejbca的官方api为什么不给出,但是这个方法是不推荐的,因为注意到execute方法的参数是一个string数组,这就意味着我们可以出错的概率大大增加,他实际上用的是UserAdminSession的addUser方法,这个方法有很多重载方法,其中官方推荐的是使用一个userDataVo的对象作为注册参数,的确这比较好。然后下面是我写的一个junit测试用例(PS:舔一下Junit的菊花,junit确实是一个好东东)。

[java]  view plain copy
  1. public class AddUser {  
  2.   
  3.     RaAddUserCommand raCommand = null;  
  4.   
  5.     @Before  
  6.     public void setUp() throws Exception {  
  7.         raCommand = new RaAddUserCommand();  
  8.     }  
  9.   
  10.     @Test  
  11.     public void test() {  
  12.         String[] args = { """xanxus1""12345",  
  13.                 "CN=xanxus""NULL""AdminCA1",  
  14.                 "xanxusiou@163.com""2""P12" };  
  15.         try {  
  16.             raCommand.execute(args);  
  17.         } catch (ErrorAdminCommandException e) {  
  18.             // TODO Auto-generated catch block  
  19.             e.printStackTrace();  
  20.         }  
  21.     }  
  22.   
  23. }  


这里解释一下参数的含义,第一个是没意义的,所以为空字符串,接着是用户名,密码,dn(这个需要注意,必须要有cn,而且cn必须是唯一的),subjectAltName(这个没什么用,就NULL吧),ca名字,用户邮箱,用户类型(2是终端用户),最后的是证书类型(这里是pkcs12)。

为用户导出证书:这里就不能简单的使用junit测试了,因为我们需要使用ejb远程调用,所以我们需要创建一个web工程,放在jboss环境下。然后我们创建一个servlet,在dopost里面导出证书吧(注意,必须是post里),代码如下:

[java]  view plain copy
  1. protected void doPost(HttpServletRequest request,  
  2.         HttpServletResponse response) throws ServletException, IOException {  
  3.     // TODO Auto-generated method stub  
  4.     response.setContentType("text/html;charset=UTF-8");  
  5.   
  6.     String name = request.getParameter("name");  
  7.     String password = request.getParameter("password");  
  8.   
  9.     try {  
  10.         Context jndiContext = new InitialContext();  
  11.         UserAdminSessionLocal userAdminSession = (UserAdminSessionLocal) jndiContext  
  12.                 .lookup("ejbca/UserAdminSessionBean/local");  
  13.         AuthenticationSessionLocal authenticationSession = (AuthenticationSessionLocal) jndiContext  
  14.                 .lookup("ejbca/AuthenticationSessionBean/local");  
  15.         CAAdminSessionLocal caAdminSession = (CAAdminSessionLocal) jndiContext  
  16.                 .lookup("ejbca/CAAdminSessionBean/local");  
  17.         KeyRecoverySessionLocal keyRecoverySession = (KeyRecoverySessionLocal) jndiContext  
  18.                 .lookup("ejbca/KeyRecoverySessionBean/local");  
  19.         SignSessionLocal signSession = (SignSessionLocal) jndiContext  
  20.                 .lookup("ejbca/RSASignSessionBean/local");  
  21.         EndEntityProfileSessionLocal endEntityProfileSession = (EndEntityProfileSessionLocal) jndiContext  
  22.                 .lookup("ejbca/EndEntityProfileSessionBean/local");  
  23.         Admin admin = new Admin(Admin.TYPE_PUBLIC_WEB_USER,  
  24.                 request.getRemoteAddr());  
  25.         UserDataVO user = userAdminSession.findUser(new Admin(  
  26.                 Admin.TYPE_PUBLIC_WEB_USER), name);  
  27.         GlobalConfigurationSessionLocal globalConfigurationSession = (GlobalConfigurationSessionLocal) jndiContext  
  28.                 .lookup("ejbca/GlobalConfigurationSessionBean/local");  
  29.         RaAdminSessionLocal raAdminSession = (RaAdminSessionLocal) jndiContext  
  30.                 .lookup("ejbca/RaAdminSessionBean/local");  
  31.         CertificateProfileSessionLocal certificateProfileSession = (CertificateProfileSessionLocal) jndiContext  
  32.                 .lookup("ejbca/CertificateProfileSessionBean/local");  
  33.           
  34.         boolean usekeyrecovery = false;  
  35.         usekeyrecovery = globalConfigurationSession  
  36.                 .getCachedGlobalConfiguration(admin).getEnableKeyRecovery();  
  37.         // 生成证书  
  38.         boolean savekeys = user.getKeyRecoverable()  
  39.                 && usekeyrecovery  
  40.                 && (user.getStatus() != UserDataConstants.STATUS_KEYRECOVERY);  
  41.         boolean loadkeys = (user.getStatus() == UserDataConstants.STATUS_KEYRECOVERY)  
  42.                 && usekeyrecovery;  
  43.   
  44.         int endEntityProfileId = user.getEndEntityProfileId();  
  45.         int certificateProfileId = user.getCertificateProfileId();  
  46.         EndEntityProfile endEntityProfile = endEntityProfileSession  
  47.                 .getEndEntityProfile(admin, endEntityProfileId);  
  48.         boolean reusecertificate = endEntityProfile  
  49.                 .getReUseKeyRecoveredCertificate();  
  50.         GenerateToken token = new GenerateToken(authenticationSession,  
  51.                 userAdminSession, caAdminSession, keyRecoverySession,  
  52.                 signSession);  
  53.         KeyStore keyStore = token.generateOrKeyRecoverToken(admin, name,  
  54.                 password, user.getCAId(), "1024",  
  55.                 AlgorithmConstants.KEYALGORITHM_RSA, false, loadkeys,  
  56.                 savekeys, reusecertificate, endEntityProfileId);  
  57.         System.out.println("size:" + keyStore.size());  
  58.         sendP12Token(keyStore, name, password, response);  
  59.     } catch (Exception exception) {  
  60.         exception.printStackTrace();  
  61.     }  
  62.   
  63. }  
  64.   
  65. private void sendP12Token(KeyStore ks, String username, String kspassword,  
  66.         HttpServletResponse out) throws Exception {  
  67.     ByteArrayOutputStream buffer = new ByteArrayOutputStream();  
  68.     ks.store(buffer, kspassword.toCharArray());  
  69.   
  70.     out.setContentType("application/x-pkcs12");  
  71.     out.setHeader("Content-disposition""filename=" + username + ".p12");  
  72.     out.setContentLength(buffer.size());  
  73.     buffer.writeTo(out.getOutputStream());  
  74.     out.flushBuffer();  
  75.     buffer.close();  
  76. }  

首先,导出用户的前提是你必须已经在jboss里部署好ejbca,然后第一步是使用jndi找出远程对象,使用lookup方法,参数可以从jboss的jndiview里找出,注意这里都是local对象,接着就是使用GenerateToken对象生成keystore,有一个false参数代表生成的是p12证书,还能指定密码的长度和算法,最后就是使用response输出证书。

以上就是目前为止我看ejbca的成果,以后会继续更新,ejbca资料实在太少,希望大家一起努力,共同研究。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值