我尝试使用 Java 中的 HSM 签署 Office 文档。 当我使用 p12 或 pfx 文件时。签名成功,没有问题。但是当我尝试使用 HSM (Utimaco) 来执行此操作时,出现异常: java.lang.UnsupportedOperationException: Private Exponent value issensitive。 可能在 Apache Poi 中,不允许从 HSM 加载私钥。 我可以签署 pdf(使用 itext)ỏ 使用 HSM 签署 XML => 没问题
这种情况我该怎么办?
我希望有人能解决我的问题并帮助我。 非常感谢!
这是我通过IAIK连接HSM的方法。我使用 github 中 POI 的示例签名文档。
public IAIKPkcs11 initProvider() throws KMSException {
Properties pkcs11ProviderConfig = new Properties();
pkcs11ProviderConfig.setProperty(Constants.PKCS11_NATIVE_MODULE, pkcs11Module);
Module pkcs11Module = IAIKPkcs11.getModule(pkcs11ProviderConfig);
try {
log.info(" ********** Connect HSM **********");
log.info(" **/ PKCS#11 Module: " + pkcs11Module + " /**");
log.info(" **/ Slot Label: " + slotLabel + " /**");
log.info(" **/ Slot Pin: " + StringCommon.hidePinCode(slotPin) + " /**");
Slot[] slotList = pkcs11Module.getSlotList(Module.SlotRequirement.ALL_SLOTS);
Integer slotIndex = null;
String slotID = "";
for (int i = 0; i < slotList.length; i++) {
if (!StringUtils.isBlank(slotList[i].getToken().getTokenInfo().getLabel())
&& slotLabel.trim().equals(slotList[i].getToken().getTokenInfo().getLabel().trim())) {
slotIndex = i;
break;
}
}
slotID = "[" + String.valueOf(slotIndex) + "]";
pkcs11ProviderConfig.setProperty(Constants.SLOT_ID, slotID);
pkcs11ProviderConfig.setProperty(Constants.USER_PIN, slotPin);
IAIKPkcs11 pkcs11Provider = new IAIKPkcs11(pkcs11ProviderConfig);
Security.addProvider(pkcs11Provider);
log.info(" **/ Provider Info: " + pkcs11Provider + " /**");
log.info(" ********** Connect HSM **********");
return pkcs11Provider;
} catch (Exception e) {
// TODO: handle exception
Sentry.captureException(e);
log.error(e.getMessage());
throw new KMSException(ErrorCode.ERROR_CONNECT_HSM, e.getMessage());
}
}
这是签名方法:
OPCPackage pkg = null;
try {
pkg = OPCPackage.open(tempDoc);
} catch (InvalidFormatException ex) {
ex.printStackTrace();
}
Provider provider = null;
if (StringUtils.equalsIgnoreCase(env.getProperty("hsm.test"), Constant.TRUE)) {
provider = new BouncyCastleProvider();
Security.addProvider(provider);
} else {
ProviderConfig providerConfig = new ProviderConfig(cryptoSource.getModule(), cryptoSource.getSlot(),
cryptoSource.getPin());
provider = providerConfig.getProvider();
Security.addProvider(provider);
}
SignatureConfig sic = new SignatureConfig();
sic.setKey(keyAndCert.getPrivateKey());
sic.setSigningCertificateChain(Collections.singletonList(keyAndCert.getCertificate()));
sic.setIncludeEntireCertificateChain(false);
sic.setSignatureDescription("Thích");
sic.setExecutionTime(new Date());
SignatureInfo si = new SignatureInfo();
si.setSignatureConfig(sic);
si.setOpcPackage(pkg);
si.confirmSignature();
boolean b = si.verifySignature();
assert (b);
pkg.close();
byte[] bFile = FileUtils.readFileToByteArray(new File(tempDoc));
if (StringUtils.equalsIgnoreCase(env.getProperty("hsm.test"), Constant.TRUE)) {
String DEST = "F://" + UUID.randomUUID() + ".doc";
File f = new File(DEST);
FileOutputStream outputStream = new FileOutputStream(f);
outputStream.write(bFile);
outputStream.flush();
outputStream.close();
}