使用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,无法完成初始化。
咨询问题
- 该场景下提示“无RSA/ECB/PKCS1Padding算法”的原因是什么?
- 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算法”的原因
- 算法映射不匹配:Java标准的
RSA/ECB/PKCS1Padding对应PKCS11标准的CKM_RSA_PKCS算法,但Sun PKCS11 Provider可能未将Java算法名正确映射到OpenSC驱动提供的PKCS11算法ID,导致无法识别。 - 密钥权限限制:通过pkcs15-init生成密钥时,可能未开启
CKA_DECRYPT属性。ePass2003作为PKCS15设备,默认生成的密钥可能仅用于签名操作,不支持解密,驱动因此无法提供对应算法支持。 - 驱动兼容性问题:使用的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,提问作者周宁音
相关产品推荐
相关产品推荐

