我试图用IText 7(‘com.itextpdf:IText 7-core:7.1.17’)在GOST3410算法上对安卓(api 26)上的pdf文档进行数字签名。BouncyCastle库:‘org.奖品库:bcprov-jdk15on:1.54’和‘org.奖品库:bcpkix-jdk15on:1.54’,这是我的函数:
fun redButton(
pdfByteArray: ByteArray,
certificates: Array<java.security.cert.Certificate>,
privateKey: PrivateKey,
contentResolver: ContentResolver,
outUri: Uri
) {
val provider = BouncyCastleProvider()
Security.removeProvider(provider.name)
Security.addProvider(provider)
val pdfInputStream = ByteArrayInputStream(pdfByteArray)
val reader = PdfReader(pdfInputStream)
val outputStream = contentResolver.openOutputStream(outUri)
val signer = PdfSigner(reader, outputStream, false)
val appearance = signer.signatureAppearance
appearance.reason = "study"
appearance.setReuseAppearance(false)
val privateKeySignature = PrivateKeySignature(
privateKey,
"GOST3411",
provider.name
)
val bouncyCastleDigest = BouncyCastleDigest()
signer.signDetached(
bouncyCastleDigest,
privateKeySignature,
certificates,
null,
null,
null,
0,
PdfSigner.CryptoStandard.CMS
)
}此代码引发异常:
com.itextpdf.kernel.PdfException: Unknown key algorithm: ECGOST3410.
at com.itextpdf.signatures.PdfPKCS7.setExternalDigest(PdfPKCS7.java:695)
at com.itextpdf.signatures.PdfSigner.signDetached(PdfSigner.java:646)
at com.itextpdf.signatures.PdfSigner.signDetached(PdfSigner.java:538)
at com.example.digitalsignature.app.services.SigningTestIText.redButton(SigningTestIText.kt:38)如果这个库不支持GOST3410,我可以在pdf文件中的签名空间中写我的自定义字节数组吗?
发布于 2022-03-19 22:39:37
正如mkl所说,实现IExternalSignatureContainer的自定义签名容器运行良好。下面是来自PrivateKeySignatureContainerBC的类示例
class PrivateKeySignatureContainerBC(
signatureAlgorithm: String?,
privateKey: PrivateKey?,
private val x509Certificate: X509Certificate,
private val subfilter: PdfName
) : IExternalSignatureContainer {
override fun sign(data: InputStream): ByteArray {
return try {
val msg: CMSTypedData = CMSTypedDataInputStream(data)
val signCert = X509CertificateHolder(x509Certificate.encoded)
val gen = CMSSignedDataGenerator()
gen.addSignerInfoGenerator(
JcaSignerInfoGeneratorBuilder(
JcaDigestCalculatorProviderBuilder().setProvider("BC").build()
)
.build(contentSigner, signCert)
)
gen.addCertificates(JcaCertStore(Collections.singleton(signCert)))
val sigData = gen.generate(msg, false)
sigData.encoded
} catch (e: IOException) {
throw GeneralSecurityException(e)
}
}
override fun modifySigningDictionary(signDic: PdfDictionary) {
signDic.put(PdfName.Filter, PdfName("MKLx_GENERIC_SIGNER"))
signDic.put(PdfName.SubFilter, subfilter)
}
private val contentSigner: ContentSigner = JcaContentSignerBuilder(signatureAlgorithm).build(privateKey)
internal inner class CMSTypedDataInputStream(var `in`: InputStream) : CMSTypedData {
override fun getContentType(): ASN1ObjectIdentifier {
return PKCSObjectIdentifiers.data
}
override fun getContent(): Any {
return `in`
}
override fun write(out: OutputStream) {
val buffer = ByteArray(8 * 1024)
var read: Int
while (`in`.read(buffer).also { read = it } != -1) {
out.write(buffer, 0, read)
}
`in`.close()
}
}
}signer.signExternalContainer建议的类调用
signer.signExternalContainer(
PrivateKeySignatureContainerBC(
"GOST3411withECGOST3410",
privateKey,
certificate,
PdfName.Adbe_pkcs7_detached
),
_estimatedSize
)https://stackoverflow.com/questions/69787567
复制相似问题