ejbca9.0集成eToken 5110

docker 映射到/dev:/dev,设置ejbca容器privileged权限

services:
  ejbca:
    image: keyfactor/ejbca-ce
    hostname: ca.hetao.me
    restart: always
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./data/ejbca/persistent:/mnt/persistent
      - ./data/ejbca/external:/mnt/external
      - ./data/ejbca/pkcs11:/opt/pkcs11
      - ./data/ejbca/pkcs11/99-deny-all.rules:/etc/polkit-1/rules.d/99-deny-all.rules
      - ./data/ejbca/conf/web.properties:/opt/keyfactor/ejbca/conf/web.properties
      - /dev:/dev
    ports:
      - 192.168.33.38:443:8443/tcp
      - 192.168.33.38:80:8080/tcp
        # devices:
        #- /dev/bus/usb
    privileged: true
    environment:
      - "TLS_SETUP_ENABLED=later"
      - "PROXY_HTTP_BIND=0.0.0.0"
      - "TZ=Asia/Shanghai"

执行

microdnf install chkconfig pcsc-lite procps-ng opensc vi usbutils psmisc tar gzip -y 
rpm -i SafenetAuthenticationClient-core-10.8.1050-1.el9.x86_64.rpm

web.properties添加以下内容

cryptotoken.p11.lib.200.name=eToken
cryptotoken.p11.lib.200.file=/usr/lib64/libeToken.so

执行以下命令,开启java的pkcs11功能

echo -e "\nJAVA_OPTS=\"\$JAVA_OPTS --add-exports=jdk.crypto.cryptoki/sun.security.pkcs11.wrapper=ALL-UNNAMED\"" >> /opt/keyfactor/appserver/bin/standalone.conf

创建/etc/polkit-1/rules.d/99-deny-all.rules并添加以下内容

polkit.addRule(function(action, subject) {
    return polkit.Result.YES;
});

然后执行

systemctl daemon-reload && systemctl daemon-reexec(如果有systemctl的话)

/opt/keyfactor/appserver/bin/jboss-cli.sh --connect ':reload'

最后只是调出了pkcs11 token的选项,并不能正常使用pkcs11 token(容器中缺少必要的组件和安全服务(polkit))
在原生Linux中用上述方法是能成功的

同样的方法也适用于基于OpenSC的ePass2003,但是OpenSC似乎不完善,会出现RSA签名无法通过验证,etoken 5110生成密钥速度慢,但还算稳定,在almalinux和ubuntu上都没有任何问题,就是linux上的驱动不好找。

后来分析了pcscd以及polkit的日志及源码,发现是polkit启动的时候依懒dbus服务,容器中无法启动dbus服务。但是新版本的pcscd提供了选项可以在编译时和运行时禁用polkit的支持。
重新编译最新版本的pcsc,然后以以下命令启动即可:

tar -zxf pcsc.tar.gz -C / --strip-components 1
tar -zxf ccid.tar.gz -C / --strip-components 1
pcscd --disable-polkit

使用中发现如果pcscd进程重启后,java进程也要重启,不然会报Token has been removed的异常。

对于ePass2003无法执行RSA签名的问题可以通过
update-crypto-policies --set LEGACY
来修复

通过参考这里的方法:https://github.com/Keyfactor/keyfactorcommunity/blob/main/hsm-integration/hsm-driver-smartcard-hsm/README.md
我有了更好的解决方案

services:
  ejbca:
    image: keyfactor/ejbca-ce
    hostname: ca.hetao.me
    restart: always
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./data/ejbca/persistent:/mnt/persistent
      - ./data/ejbca/external:/mnt/external
      - ./data/ejbca/conf/web.properties:/opt/keyfactor/ejbca/conf/web.properties
      - ./data/ejbca/conf/standalone.conf:/opt/keyfactor/wildfly-33.0.0.Final/bin/standalone.conf 
      - /lib/x86_64-linux-gnu/libpcsclite.so.1.0.0:/usr/lib64/libpcsclite.so.1.0.0:ro
      - /lib/x86_64-linux-gnu/libpcsclite.so.1.0.0:/usr/lib64/libpcsclite.so.1:ro
      - ./data/ejbca/pkcs11/libeToken.so:/usr/lib64/pkcs11/libeToken.so:ro
      - ./data/ejbca/pkcs11/libeToken.so:/usr/lib64/libeToken.so:ro
      - /var/run/pcscd:/var/run/pcscd:ro
    ports:
      - 192.168.33.38:443:8443/tcp
      - 192.168.33.38:80:8080/tcp

以这种方式创建ebjca容器可以在在ejbca中直接使用eToken5110。
原理是在缩主机上运行pcscd服务,在容器中运行pcsc客户端功能,需要把pcsc的socket(/var/run/pcscd/pcscd.comm)和客户端(libpcsclite.so)库映射到容器中。
eToken的pkcs11库可以从rpm包中提取出来映射到容器中,至于OpenSC也不是eToken必须的,这样就不需要在容器中安装任何软件了。

其它问题

  • 修复ePass2003 RSA密钥无法签名的问题

在cesecore.properties中添加以下配置

pkcs11.disableHashingSignMechanisms=false

这样在签名时不使用java自己的hash,而是使用hsm内置的hash,有些token不允许在外部进行hash.
这样修改后以前生成的CA证书会失效,需要注意。

参考:
https://www.smartcard-hsm.com/2014/09/05/Accessing_your_SmartCard-HSM_from_EJBCA.html
https://doc.primekey.com/ejbca/ejbca-integration/hardware-security-modules-hsm/nitrokey-hsm

发表回复