IText 7 未知密钥算法:ECGOST3410
IText 7 Unknown key algorithm: ECGOST3410
我正在尝试使用 IText 7('com.itextpdf:itext7-core:7.1.17') 在 android (api 26) 上对 pdf 文档进行数字签名GOST3410 算法。 BouncyCastle 库:'org.bouncycastle:bcprov-jdk15on:1.54' 和 'org.bouncycastle: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 文件的签名 space 中写入自定义字节数组吗?
作为mkl said custom signature container implementing IExternalSignatureContainer
works well. Here's class example from 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()
}
}
}
建议 class 致电 signer.signExternalContainer
:
signer.signExternalContainer(
PrivateKeySignatureContainerBC(
"GOST3411withECGOST3410",
privateKey,
certificate,
PdfName.Adbe_pkcs7_detached
),
_estimatedSize
)
我正在尝试使用 IText 7('com.itextpdf:itext7-core:7.1.17') 在 android (api 26) 上对 pdf 文档进行数字签名GOST3410 算法。 BouncyCastle 库:'org.bouncycastle:bcprov-jdk15on:1.54' 和 'org.bouncycastle: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 文件的签名 space 中写入自定义字节数组吗?
作为mkl said custom signature container implementing IExternalSignatureContainer
works well. Here's class example from 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()
}
}
}
建议 class 致电 signer.signExternalContainer
:
signer.signExternalContainer(
PrivateKeySignatureContainerBC(
"GOST3411withECGOST3410",
privateKey,
certificate,
PdfName.Adbe_pkcs7_detached
),
_estimatedSize
)