I need to verify digital signature in a pdf file.
I use itextpdf
and cryptopro
cryptopro
provides these aliases for the needed algorithm:
, JCP: Signature.GOST3411withGOST3410EL -> ru.CryptoPro.JCP.Sign.GostElSign
aliases: [1.2.643.2.2.3, OID.1.2.643.2.2.3, 1.2.643.2.2.9with1.2.643.2.2.19]
itextpdf
tries to get "GOST3411withECGOST3410" and fails with: "no such algorithm: GOST3411withECGOST3410 for provider JCP"
This works:
Provider prov = Security.getProvider(PROVIDER_NAME);
prov.put("Alg.Alias.Signature.GOST3411withECGOST3410", "GOST3411withGOST3410EL");
Not sure it's a correct way though.
Exception in thread "main" ExceptionConverter: java.security.NoSuchAlgorithmException: no such algorithm: GOST3411withECGOST3410 for provider JCP
at sun.security.jca.GetInstance.getService(GetInstance.java:70)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:190)
at java.security.Signature.getInstance(Signature.java:324)
at com.itextpdf.text.pdf.security.PdfPKCS7.initSignature(PdfPKCS7.java:692)
at com.itextpdf.text.pdf.security.PdfPKCS7.<init>(PdfPKCS7.java:452)
at com.itextpdf.text.pdf.AcroFields.verifySignature(AcroFields.java:2349)
at org.foo.PdfVerifier.verify(PdfVerifier.java:83)
at org.foo.PdfVerifier.main(PdfVerifier.java:53)
What you do is Ok and practically you have no other choice.
However, the true problem lies in the way
itextpdf
works. It hardcodes BouncyCastle's names for key algorithmsECGOST3410
, while CryptoPro JCP has theGOST3410EL
name for the same algorithm. This makes it difficult to switch to use keys produced by different security provider like in your case.The library can get the same values from keys using Key.getAlgorithm(), which will eliminate the need for hardcoding and make the library less "security provider dependent." Hardcoding is an especially bad idea taking into account that PdfPKCS7 constructor allows security provider selection.