EJBCA操作说明(二)java操作

ejbca web界面操作

代码下载地址

  • 初始化获得EJBCA实例
	/**
	 * 初始化EjbcaWS,获得EJBCA服务端Webservice实例
	 * @return
	 */
	public static EjbcaWS init() 
	{		
		EjbcaWS ejbcaWS = null;
		CryptoProviderTools.installBCProvider();
		System.setProperty("javax.net.ssl.keyStore","C:/Users/mango/Desktop/superadmin.p12");
		System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
		Provider tlsProvider = new TLSProvider();
		Security.addProvider(tlsProvider);
		Security.setProperty("ssl.TrustManagerFactory.algorithm", "AcceptAll");
		System.setProperty("javax.net.ssl.keyStorePassword", "e9a7d6bb701cfba8b0f20de5b8e92d1cf9c1f4f0");
		try 
		{
			KeyManagerFactory.getInstance("NewSunX509");
		} 
		catch (NoSuchAlgorithmException e1) 
		{	
			e1.printStackTrace();
		}
		Security.setProperty("ssl.KeyManagerFactory.algorithm", "NewSunX509");
 
		QName qname = new QName("http://ws.protocol.core.ejbca.org/","EjbcaWSService");
		EjbcaWSService service = null;
		try {
			service = new EjbcaWSService(new URL("https://ejbcatest:8443/ejbca/ejbcaws/ejbcaws?wsdl"), qname);
			ejbcaWS = service.getEjbcaWSPort();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		return ejbcaWS;
	}

采用域名的方式访问EJBCA服务端,则需要在客户端所在服务器hosts文件中加入服务器域名和IP。

 

  • 注册和更新终端实体

 

	/**
	 * 
	* @Title: editUser
	* @Description: 添加用户实例或更新用户实体
	* @param @param ejbcaWS
	* @param @param userName
	* @param @param passWord
	* @param @param caName
	* @param @throws ApprovalException_Exception
	* @param @throws AuthorizationDeniedException_Exception
	* @param @throws CADoesntExistsException_Exception
	* @param @throws EjbcaException_Exception
	* @param @throws UserDoesntFullfillEndEntityProfile_Exception
	* @param @throws WaitingForApprovalException_Exception
	* @param @throws IllegalQueryException_Exception
	* @param @throws EndEntityProfileNotFoundException_Exception    参数
	* @return void    返回类型
	* @throws
	 */
public static void  editUser(EjbcaWS ejbcaWS, String userName, String passWord, String caName, String certType) throws ApprovalException_Exception, AuthorizationDeniedException_Exception,
CADoesntExistsException_Exception, EjbcaException_Exception, UserDoesntFullfillEndEntityProfile_Exception,
 WaitingForApprovalException_Exception, IllegalQueryException_Exception, EndEntityProfileNotFoundException_Exception {

  // Test to add a user.
       final UserDataVOWS user = new UserDataVOWS();
       user.setUsername(userName);
       user.setPassword(passWord);
       user.setClearPwd(true);
       user.setSubjectDN("CN=" + userName);
       user.setCaName(caName);
       user.setEmail(null);
       user.setSubjectAltName(null);
       user.setStatus(EndEntityConstants.STATUS_NEW);
       user.setTokenType(certType);
       user.setEndEntityProfileName("EMPTY");
       user.setCertificateProfileName("ENDUSER");
       String pattern = "yyyy-MM-dd HH:mm:ssZZ"; // ISO 8601标准时间格式
       user.setStartTime(DateFormatUtils.format(new Date(),pattern));//证书有效起始日期
       user.setEndTime(DateFormatUtils.format(DateUtils.addDays(new Date(), 100), pattern));//结束日期

       ejbcaWS.editUser(user);


   }
  • 查找终端实体
  • 		/**
    		 * 检查用户实体是否存在
    		 * @param ejbcaWS
    		 * @param username
    		 * @return
    		 * @throws Exception
    		 */
    		public static boolean isExist(EjbcaWS ejbcaWS, 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());
    	    }
    	}

     

  • 吊销并删除终端实体

     
        /**
         *
         * @Title: revokeUser
         * @Description: 吊销证书
         * @param @param ejbcaWS
         * @param @param userName
         * @return void    返回类型
         * @throws
         */
    	public static void revokeUser(EjbcaWS ejbcaWS, String userName) throws Exception 
    	{
    	
    	    // Revoke and delete
    		ejbcaWS.revokeUser(userName, RevokedCertInfo.REVOCATION_REASON_KEYCOMPROMISE, true);
    	
    	    UserMatch usermatch = new UserMatch();
    	    usermatch.setMatchwith(UserMatch.MATCH_WITH_USERNAME);
    	    usermatch.setMatchtype(UserMatch.MATCH_TYPE_EQUALS);
    	    usermatch.setMatchvalue(userName);
    	    List<UserDataVOWS> userdatas = ejbcaWS.findUser(usermatch);
            if (userdatas != null && userdatas.size() > 0) 
            {
                System.out.println("revoke failed!");
            } 
            else 
            {
            	
            	System.out.println("revoke successfully!");
            }	
    	}

     

true表示是否删除用户。

 

  • 获取证书
	public static List<Certificate> findCert(EjbcaWS ejbcaWS, String certName) throws AuthorizationDeniedException_Exception, EjbcaException_Exception
	{
		//第一个入参为实体名还是证书名?, 	End entity
		   List<Certificate> foundcerts = ejbcaWS.findCerts(certName, true);
		   return foundcerts;
	}
	

获取某个终端实体的所有证书,true表示只查找有效的证书。

	public static List<Certificate> getLastCAChainCert(EjbcaWS ejbcaWS, String caName) throws AuthorizationDeniedException_Exception, EjbcaException_Exception, CADoesntExistsException_Exception
	{
		   //入参为CA名 
		   List<Certificate> foundcerts = ejbcaWS.getLastCAChain(caName);
		   return foundcerts;
	}

根据证书16进制序列号及颁发者DN获取证书。

	public static Certificate getCert(EjbcaWS ejbcaWS, String certSNinHex, String issuerDN) throws AuthorizationDeniedException_Exception, EjbcaException_Exception, CADoesntExistsException_Exception
	{
		//第一个入参为证书序列号,第二个参数为颁发者DN
		Certificate foundcerts = ejbcaWS.getCertificate(certSNinHex, issuerDN);
		return foundcerts;
	}
	
  • 申请证书

根据已注册终端实体申请包含公私钥及证书的pkcs12文件

/**
	 * 
	* @Title: createCert
	* @Description: 根据用户实体名称密码申请pkcs12证书
	* @param @param ejbcaWS
	* @param @param username
	* @param @param password
	* @param @param path
	* @param @throws Exception    参数
	* @return void    返回类型
	* @throws
	 */
	public static void createCert(EjbcaWS ejbcaWS,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) {
	            }
	        }
	    }
	}

根据CSR请求申请pem格式证书

certificateResponse = ejbcaWS.certificateRequest(userDataVOWS, pkcs10AsBase64, CertificateHelper.CERT_REQ_TYPE_PKCS10, null, CertificateHelper.RESPONSETYPE_CERTIFICATE);

userDataVOWS:用户信息,用户名必填

pkcs10AsBase64: CSR请求

同一个用户可以创建多份证书,与web界面申请证书规则不同。

 

  • 吊销证书
    /**
     * @param  issuerDN 颁发者DN
     * @param  reason 吊销证书的原因
     * @return List<Certificate>  查询到的证书列表
     * @throws
     * @Title: revokeUser
     * @Description: 吊销证书
     */
    public static void revokeCert(final String issuerDN, final String certificateSN, final int reason) throws Exception {
        //第一个入参为证书颁发者DN,第二个参数为证书序列号
        ejbcaWS.revokeCert(issuerDN, certificateSN, reason);

    }

 

  • 获取证书吊销列表
   /**
     * 
    * @Title: getCRL
    * @Description: 获取某个CA的证书吊销列表
    * @param @param ejbcaWS
    * @param @param caName	CA名称
    * @param @param delta	是否为增量
    * @param @return
    * @param @throws CADoesntExistsException_Exception
    * @param @throws EjbcaException_Exception
    * @param @throws CRLException    参数
    * @return int    返回类型
    * @throws
     */
    public static Set<? extends X509CRLEntry> getCRL(EjbcaWS ejbcaWS, final String caName, final boolean delta) throws CADoesntExistsException_Exception, EjbcaException_Exception, CRLException {
        final byte[] crlBytes = ejbcaWS.getLatestCRL(caName, delta);
        if(crlBytes == null)
        {
        	return null;
        }
        final X509CRL crl = CertTools.getCRLfromByteArray(crlBytes);
        final Set crls = crl.getRevokedCertificates();
        final BigInteger crlNumber = CrlExtensions.getCrlNumber(crl);
        System.out.println(crl.getIssuerDN());
        System.out.println(crl.getThisUpdate());
        System.out.println(crl.getNextUpdate());
        System.out.println(crlNumber.intValue());
        X509CRLEntry entry = crl.getRevokedCertificate(new BigInteger("8805361580365352127"));
        if (entry != null) {
            String time = new SimpleDateFormat("yyyyMMddHHmmss").format(entry.getRevocationDate());
            System.out.println(entry.getSerialNumber());
            System.out.println(entry.getRevocationReason());
            System.out.println(entry.getCertificateIssuer());
        }

        
        return crls;
    }

注意CA的CRL列表不能实时更新,有滞后性,一般一天更新一次。

  • 证书验证
  • 验证证书链
 /**
     * 
    * @Title: verifyEffect
    * @Description: 验证证书链
    * @param @param ejbcaWS
    * @param @param foundcerts
    * @param @return    参数
    * @return boolean    返回类型
    * @throws
     */
    public static boolean verifyEffect(EjbcaWS ejbcaWS,List<Certificate> foundcerts){ 
        boolean effectFlag = false;
        try 
        {
        	System.out.println("foundcerts.size:"+foundcerts.size());
        	java.security.cert.Certificate cert = 
        			(java.security.cert.Certificate) CertificateHelper.getCertificate(foundcerts.get(0).getCertificateData());
			System.out.println("client SubjectDN:"+ CertTools.getSubjectDN(cert));
			System.out.println("client IssuerDN:"+ CertTools.getIssuerDN(cert));
			System.out.println("client SerialNumber:"+ CertTools.getSerialNumber(cert));
			for(int i = 1 ;i < foundcerts.size(); i++)
			{
				java.security.cert.Certificate cert2 = 
						(java.security.cert.Certificate)CertificateHelper.getCertificate(foundcerts.get(i).getCertificateData());
				System.out.println("service SubjectDN:"+ CertTools.getSubjectDN(cert2));
				System.out.println("service IssuerDN:"+ CertTools.getIssuerDN(cert2));
				System.out.println("service SerialNumber:"+ CertTools.getSerialNumber(cert2));
				cert.verify(cert2.getPublicKey());
				effectFlag = true;
			}
        }
        catch (Exception e) {
			System.out.println(e.getMessage());
		}
        return effectFlag;
        
    }

 

  • 验证证书有效性
    /**
     * <p>
     * 验证证书是否过期或无效
     * </p>
     * 
     * @param date 日期
     * @param certificate 证书
     * @return
     */
    public static boolean verifyCertificate(Date date,java.security.cert.Certificate certificate) {
        boolean isValid = true;
        try {
            X509Certificate x509Certificate = (X509Certificate)certificate;
            x509Certificate.checkValidity(date);
            System.out.println("cert valid");
        } catch (Exception e) {
        	System.out.println(e.getMessage());
            isValid = false;
        }
        return isValid;
    }

 

  • 验证签名
    
    /**
     * <p>
     * 验证签名
     * </p>
     * 
     * @param data 已加密数据
     * @param sign 数据签名[BASE64]
     * @param certificatePath 证书存储路径
     * @return
     * @throws Exception
     */
    public static boolean verifySign(byte[] data, String sign, java.security.cert.Certificate certificate) 
            throws Exception {
        // 获得证书
        X509Certificate x509Certificate = (X509Certificate) certificate;
        // 获得公钥
        PublicKey publicKey = x509Certificate.getPublicKey();
        // 构建签名
        Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
        signature.initVerify(publicKey);
        signature.update(data);
//        return signature.verify((sign));
        return true;
    }

 

  1. 遗留问题

1.EJBCA提供了JAVA SDK去调用其Webservice接口,初始化时获取了EJBCA的EjbcaWSService实例,并需要设置证书。如果使用手机客户端直接访问EJBCA的话APP是否能获得该实例,如何配置证书等。EJBCA是否提供了手机APP集成时需要使用的SDK?

2.获取Ejbca实例客户端需要配置超级管理员证书,该证书拥有删除用户,修改用户,注册CA等一系列敏感权限,如果手机直接集成的话会存在危险。目前看可以在管理员界面对该证书的权限进行配置。

3.部署环境时需要修改ejbca-setup.sh脚本中的httpsserver_hostname为部署所在服务器的主机名称,这样在生成EJBCA HTTPS服务端证书时证书Domain Name与服务器域名相同,客户端才可以通过域名正常访问。如果通过IP访问则还需要修改ejbca-setup.sh脚本。

后面我会把操作的代码打包放到资源里面,大家可以下载

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值