《转载请注明出处》
摸索这个东西好长时间了,资料太少无从下手找了个EJBCA的类似论坛的东西 一点点找入口.....
分享下:http://sourceforge.net/p/ejbca/discussion/132019/,这个EJBCA的论坛 有问题 里面的人很快会回答的,但是 他们是做盈利机构的有些问题。。
EJBCA SVN路径:https://svn.cesecore.eu/svn/ejbca/tags/Rel_3_9_7/ejbca 这是3的版本。
其他的版本到:https://svn.cesecore.eu/svn/ejbca/tags 这里选。
一、先介绍下接口调用:
EJBCA 提供的ws接口有两种调用方式:1、直接走ws接口;2、EJBCA提供的有命令行的方式,输入命令调用ws接口
当然很多人会直接选择EJBCA提供的ws接口,我当时是实在走不动了就反复看他的API(下面英文的)才想去试试命令行的,执行一下发现JBOSS后台报错一样才明白是咋回事。
Using the Web Services CLI
Included in the EJBCA Client Tool Box is a Web Service CLI tool.
To use the client do the following,copy the directory with all included files to the computer you want to remote administrate from. Then create a JKS or P12 file with the appropriate access rights (See the Using API section for details) and finally configure the file ejbcawsracli.properties. In this file you should specify the hostname of the CA server,the name of the keystore and the password to unlock it. Documentation for each setting is in the file ejbcacsracli.properties.
Use 'ejbcaClientToolBox.sh EjbcaWsRaCli' for a list of each subcommand and 'ejbcaClientToolBox.sh EjbcaWsRaCli "subcommand"' for detailed help how to use the cli.
Example usage: ejbcaClientToolBox.sh EjbcaWsRaCli pkcs12req testuser2 foo123 2048 NONE tmp
ejbcaClientToolBox.sh EjbcaWsRaCli revokeuser testuser2 SUPERSEDED false
1、拿到根证书;
3、拿到ws接口;
三、命令调用接口介绍
先说第二种通过命令行接口:
在你安装EJBCA的目录 ejbca_4_0_10\dist\ejbca-ws-cli 下面有cmd命令和sh命令,输入后会有提示操作(但是这个命令太抽象、不是很好找)。如下图:
查找用户wsadmin的命令这样写:
<span style="font-size:18px;">ejbcawsracli.cmd finduser USERNAME Equals wsadmin</span>
然后会出来你想要的!!其他的命令我是没怎么找,太麻烦了!所以就想其他办法吧。
不要急,往下看。 当你输入more ejbca-ws-cli.cmd 显示:
显示这个命令行是封装了的jar文件,所以我们就可以反编译看他封装的源码了!!哈哈
下载svn的项目后 找到对应的路径 看看吧,他是咋调用的就很清楚了(到这里 就花了很长时间,因为没思路)。
下面介绍下我熟悉的几个接口:
到这个API的位置上看吧,里面是你基本需要的方法:
http://www.ejbca.org/ws/org/ejbca/core/protocol/ws/client/gen/EjbcaWS.html#certificateRequest(org.ejbca.core.protocol.ws.client.gen.UserDataVOWS,java.lang.String,int,java.lang.String)
四、接口示例介绍(简单介绍一个)
看ws的API按照他给的例子就是不对,下面的连接进去看吧!
http://tirnanog.ls.fi.upm.es:8080/ejbca/doc/adminguide.html#Sample code
会出现很多的异常,还不知道错在哪?
我这样是正常的----
这样设置证书的到程序中(官网他提供的API也不知道是方法太老还是太新了 ,我用的一直不对。)下面是我现在使用根证书认证的代码:
</pre><pre name="code" class="java">String urlstr = "https://localhost:8443/ejbca/ejbcaws/ejbcaws?wsdl";
CryptoProviderTools.installBCProvider();
System.setProperty("javax.net.ssl.keyStore","C:/ejbca_4_0_10/p12/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","ejbca");
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(urlstr),qname);
} catch (MalformedURLException e) {
e.printstacktrace();
}
EjbcaWS ejbcaraws = service.getEjbcaWSPort();
这样你就可以拿到需要的webService接口了。下面是查找用户的例子:
UserMatch usermatch = new Usermatch();
usermatch.setMatchwith(org.ejbca.util.query.UserMatch.MATCH_WITH_USERNAME);
usermatch.setMatchtype(org.ejbca.util.query.UserMatch.MATCH_TYPE_EQUALS);
usermatch.setMatchvalue(userName);
List<UserDataVOWS> result = ejbcaraws.findUser(usermatch);//(ejbcaraws 就是上面获取到的ws service)
简单说下这个方法的参数:
setMatchwith 和setMatchtype 这两个参数是来说明你要按照什么查找,例子中的是按用户名查,他还提供了按subjectDN和组织等的查询(自己看参数怎么传吧)
这就是最基本的操作了,下面的很多根据你需要自己看看源码看看API吧。走通这个你最起码不发愁没方向了,我是难为了2周,找文章找人问都没有 哭都哭不出来。
第一种调用法
很简单了,只要你拿到他的源码,还有啥不难办的呢?人家带的测试类带的例子那么多,你要是看不出来 就.....
把测试路径给你发出来:
思路给分析了,其他的问题可以问问哈 加EJBCA开发群:362248338
五、异常
上一篇安装时候提到的302异常(又经一起学习的哥们“希望、在前方” 验证,这个是正确的当你访问服务器时,捂手之后EJBCA会给你跳到127.0.0.1 就会报:服务器发送了 HTTP 状态
代码 302: Moved Temporarily 异常)
配置JBOSS :
修改jboss下面的目录中的
文件内容:
JOBSS_HOME
rver/default/deployers/jbossws.deployer/
meta-inf/jboss-beans.xml
注释掉
<property name="webServiceHost">${jboss.bind.address}</property>
否则在使用
代码访问wsdl时候 会出现:
ClientTransportException: 服务器发送了 HTTP 状态代码 302: Moved Temporarily 异常
六、几个常用的接口
==========================================================
====================证书验证:
==============================================
==========================================================
1、验证签名是否正确
2、验证证书是否由根CA颁发;
3、验证证书是否过期
4、属于应用层的验证,验证证书的 序列号+颁发者 和
用户的绑定关系;
====================证书
查询:
==============================================
==========================================================
ejbcaraws
.findCerts(certName,
true
);
//true 查找可用的证书;false 查找所有证书
根据参数不 true或者false来 查找不通的类型
====================用户查询接口:
==============================================
==========================================================
UserMatch usermatch =
new
Usermatch();
//
MATCH_WITH_USERNAME
= 0;//用户名
//
MATCH_WITH_EMAIL
= 1;//邮箱
//
MATCH_WITH_STATUS
= 2;
// Value must the number representation.
//
MATCH_WITH_ENDENTITYPROFILE
= 3;
// Matches the profile id not profilename.
//
MATCH_WITH_CERTIFICATEPROFILE
= 4;
// Matches the certificatetype id not name.
//
MATCH_WITH_CA
= 5;
// Matches the CA id not CA name.
//
MATCH_WITH_TOKEN
= 6;
//
MATCH_WITH_DN
= 7;
usermatch.setMatchwith(org.ejbca.util.query.UserMatch.
MATCH_WITH_USERNAME
);
//
MATCH_TYPE_EQUALS
= 0; 等于
//MATCH_TYPE_BEGINSWITH
= 1; 以什么开始
//
MATCH_TYPE_CONTAINS
= 2; 包含
usermatch.setMatchtype(org.ejbca.util.query.UserMatch.
MATCH_TYPE_EQUALS
);
usermatch.setMatchvalue(
"WSTESTUSER2"
);
ejbcaraws
.findUser(usermatch)
====================
获取私钥
==============================================
==========================================================
KeyStore result = ejbcaraws.pkcs12Req(userName,password,
null
,
"1024"
,AlgorithmConstants.
KEYALGORITHM_RSA
);
java.security.KeyStore ks2 = KeyStoreHelper.getKeyStore(result.getKeystoreData(),
"PKCS12"
,password);
Enumeration en =ks2.aliases();
System.
out
.println(
"en:"
+en);
String alias = (String) en.nextElement();
X509Certificate cert2 = (X509Certificate) ks2.getCertificate(alias);
PrivateKey privK2 = (PrivateKey)ks2.getKey(alias,
"foo456"
.tochararray());
String key2 =
new
String(Hex.encode(privK2.getEncoded()));
System.
out
.println(
"秘钥:"
+key2);
==========================================================
====================
获取公钥
==============================================
==========================================================
List<Certificate> result = ejbcaraws.findCerts(
"hangzhou"
,
true
);
Iterator<Certificate> iter = result.iterator();
while
(iter.hasNext()){
i++;
Certificate cert = iter.next();
Certificate aa = cert.getCertificate();
String certData =
new
String(cert.getCertificateData());
java.security.cert.Certificate retval = CertTools.getCertfromByteArray(Base64.decode(cert.getCertificateData()));
System.
out
.println(
"PublicKey:"
+retval.getPublicKey());
}
CertTools. getSerialNumber(retval)
PublicKey key =
ejbcaWsFactory
.getRootPublicKey();
try
{
xc.verify(key);
}
catch
(InvalidKeyException e) {
}
catch
(CertificateException e) {
}
catch
(NoSuchAlgorithmException e) {
}
catch
(NoSuchProviderException e) {
}
catch
(SignatureException e) {
}
==========================================================
====================
获取证书信息
==============================================
==========================================================
java.security.KeyStore ks = KeyStoreHelper.getKeyStore(ksenv.getKeystoreData(),
"PKCS12"
,
"foo456"
);
assertNotNull(ks);
Enumeration en = ks.aliases();
String alias = (String) en.nextElement();
X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
assertTrue(cert.getSubjectDN().toString().equals(
"CN=WSTESTUSER1,O=Test"
));
====================
获取证书
IssuerDN
SerialNumber
==============================================
==========================================================
java.security.KeyStore ks = KeyStoreHelper.getKeyStore(ksenv.getKeystoreData(),
"foo456"
);
Enumeration en = ks.aliases();
String alias = (String) en.nextElement();
X509Certificate cert = (X509Certificate ) ks.getCertificate(alias);
System.
out
.println(cert.getSubjectDN().toString().equals(
"CN=111111,O=Test"
));
String issuerdn = cert.getIssuerDN().toString();
System.
out
.println(
"第一次 IssuerDN:"
+issuerdn);
String serno = cert.getSerialNumber().toString(16);
System.
out
.println(
"第一次SerialNumber:"
+serno);
==========================================================
====================
撤销证书
=
=============================================
==========================================================
* revokeCert 方法 撤销证书(在页面上可以看到如下信息)
* 已撤销 是
撤销日期: 2014
-
05
-
29 23:55:07+08:00
撤销原因: 证书挂起
ejbcaraws.revokeCert(issuerdn,serno,6)
证书挂起后 新增还可以下载 为什么????
==========================================================
==================
编辑用户实体 获取用户密码 为null
=
==================
==========================================================
编辑用户实体时候 setClearPwd(false); 不知道什么作用 获取 passwoord 为空
==========================================================
==================简单
生成证书
=
==================
==========================================================
BatchMakeP12 makep12 =
new
BatchMakeP12();
File tmpfile = File. createTempFile(
"ejbca"
,
"p12"
);
makep12.setMainStoreDir(tmpfile.getParent());
===================================================
revokeUser("zhengzhou",1,true);
用户没了
==========================================================
验证证书链
=
==================
==========================================================
/**
* 验证签名 (根据终端用户名获取到 该用户的证书链 找到根证书,使用根证书的PublicKey验证客户端证书的有效性)
*
@return
有效true/无效false
*/
public
static
boolean
verifyEffect(String userName){
boolean
effectFlag =
false
;
try
{
List<Certificate> foundcerts =
ejbcaraws
.getLastCertChain(userName);
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(
"serive SubjectDN:"
+ CertTools.getSubjectDN(cert2));
System.
out
.println(
"serive IssuerDN:"
+ CertTools.getIssuerDN(cert2));
System.
out
.println(
"serive SerialNumber:"
+ CertTools.getSerialNumber(cert2));
//System.out.println("serive SerialNumber:"+ CertTools.get);
cert.verify(cert2.getPublicKey());
// will throw if verification fails
effectFlag =
true
;
}
}
catch
(AuthorizationDeniedException_Exception e) {
}
catch
(EjbcaException_Exception e) {
}
catch
(CertificateException e) {
}
catch
(InvalidKeyException e) {
}
catch
(NoSuchAlgorithmException e) {
}
catch
(NoSuchProviderException e) {
}
catch
(SignatureException e) {
}
return
effectFlag;
}
==========================================================
移除
证书
=
==================
==========================================================
ejbcaraws
.revokeCert(issuerdn,RevokedCertInfo.
REVOKATION_REASON_KEYCOMPROMISE
);