You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用OpenSC+PKCS11 Provider时提示缺少RSA/ECB/PKCS1Padding算法的原因

问题描述

我正在开发基于ePass2003 HSM与Sun PKCS11 Provider的加解密类,选用OpenSC作为PKCS11驱动,通过PKCS15工具初始化HSM、生成RSA密钥对并导入证书后,运行代码出现以下报错:

java.security.NoSuchAlgorithmException: No such algorithm: RSA/ECB/PKCS1Padding     
at java.base/javax.crypto.Cipher.getInstance(Cipher.java:723)     
at EncryptionModule.decryptUsingPrivateKey(EncryptionModule.java:69)     
at TestPkcs11.testEncryptAndDecrypt(TestPkcs11.java:26)     
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)     
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     
at java.base/java.lang.reflect.Method.invoke(Method.java:566)     
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)     
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)     
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)     
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)     
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:305)     
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)     
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:365)     
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)     
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)     
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:330)     
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:78)     
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:328)     
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:65)     
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:292)     
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:305)     
at org.junit.runners.ParentRunner.run(ParentRunner.java:412)     
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)     
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)     
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)     
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)     
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)     
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)     
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)

已做排查

  • 查阅Java11文档确认Sun PKCS11 Provider仅作为桥接,功能依赖底层DLL,通过SoftHSM2验证后排除该原因;
  • ePass2003文档显示支持RSA加解密与PKCS11,但因已配置为PKCS15设备无法直接验证;
  • 尝试用SoftHSM2+OpenSC复现问题,但OpenSC无法识别SoftHSM2,无法完成初始化。

咨询问题

  1. 该场景下提示“无RSA/ECB/PKCS1Padding算法”的原因是什么?
  2. OpenSC是否可搭配HSM使用?

附相关文件

Java代码

public class EncryptionModule {
    private static KeyStore keyStore;
    private static EncryptionModule encryptionModule;
    private Provider pkcs11Provider;
    private EncryptionModule() throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {
        if(keyStore==null){
            pkcs11Provider = Security.getProvider("SunPKCS11");
            pkcs11Provider = pkcs11Provider.configure("pkcs11Config.txt");
            Security.addProvider(pkcs11Provider);
            keyStore = KeyStore.getInstance("PKCS11");
            keyStore.load(null,"12345678".toCharArray());
        }
    }
    public static EncryptionModule getEncryptionModule() throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException {
        if(encryptionModule==null){
            encryptionModule = new EncryptionModule();
        }
        return encryptionModule;
    }

    public X509Certificate generateSelfSignedCertificate(KeyPair keyPair, String dn, long validity) throws GeneralSecurityException, IOException {
        Date from = new Date();
        Date to = new Date(from.getTime() + validity);
        BigInteger serialNumber = new BigInteger(64, new SecureRandom());
        X509CertInfo certInfo = new X509CertInfo();
        certInfo.set(X509CertInfo.VALIDITY, new CertificateValidity(from, to));
        certInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(serialNumber));
        certInfo.set(X509CertInfo.SUBJECT, new X500Name(dn));
        certInfo.set(X509CertInfo.ISSUER, new X500Name(dn));
        certInfo.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic()));
        certInfo.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
        AlgorithmId algo = AlgorithmId.get("SHA256withRSA");
        certInfo.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));
        X509CertImpl cert = new X509CertImpl(certInfo);
        cert.sign(keyPair.getPrivate(), "SHA256withRSA");
        return cert;
    }
    
    public byte[] encryptUsingPublicKey(String id,byte[] data) throws KeyStoreException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        PublicKey publicKey = keyStore.getCertificate(id).getPublicKey();
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }
    
    public byte[] decryptUsingPrivateKey(String id,byte[] data) throws UnrecoverableEntryException, KeyStoreException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, SignatureException, NoSuchProviderException {
            System.out.println(pkcs11Provider.getName());
            for (Provider.Service service : pkcs11Provider.getServices()) {
                System.out.println(service.getType() + ": " + service.getAlgorithm());
            }

        PrivateKey privateKey = (PrivateKey) keyStore.getKey(id, null);
        System.out.println(privateKey.getAlgorithm());
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding",pkcs11Provider);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }
}

PKCS11配置文件

name = HSMProvider 
library = opensc-pkcs11.dll 
slotListIndex = 0 

ePass2003初始化命令

pkcs15-init -E -T 
pkcs15-init --create-pkcs15 -T -p pkcs15+onepin --pin 12345678 
pkcs15-init --generate-key rsa/2048 -l "test" --auth-id 1

解答

问题1:“无RSA/ECB/PKCS1Padding算法”的原因

  1. 算法映射不匹配:Java标准的RSA/ECB/PKCS1Padding对应PKCS11标准的CKM_RSA_PKCS算法,但Sun PKCS11 Provider可能未将Java算法名正确映射到OpenSC驱动提供的PKCS11算法ID,导致无法识别。
  2. 密钥权限限制:通过pkcs15-init生成密钥时,可能未开启CKA_DECRYPT属性。ePass2003作为PKCS15设备,默认生成的密钥可能仅用于签名操作,不支持解密,驱动因此无法提供对应算法支持。
  3. 驱动兼容性问题:使用的OpenSC版本对ePass2003的PKCS11支持不完善,部分算法未正确暴露给上层Java Provider。

问题2:OpenSC是否可搭配HSM使用

OpenSC是通用PKCS11中间件,完全可以搭配符合PKCS11标准的HSM使用,但需注意:

  • 并非所有HSM都被OpenSC官方适配,小众HSM可能需要额外配置或补丁;
  • SoftHSM2是软件模拟HSM,OpenSC默认面向硬件设备,因此无法直接识别,需修改OpenSC配置或使用特定适配版本;
  • ePass2003属于智能卡类HSM,OpenSC对其有基础支持,需确保使用的OpenSC版本包含对应驱动。

内容的提问来源于stack exchange,提问作者周宁音

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 09:54:51