Hi,

we’re having an issue verifying a signature contained in a PKCS7 file which 
uses the encryption algorithm 0.4.0.127.0.7.1.1.4.1.3/ecdsa-plain-SHA256.

Platform: .NET 5.0 / Windows 10 Pro 64-bit Build 19044.1466 / Bouncycastle 
1.9.0 (from this<https://www.bouncycastle.org/csharp/index.html> page)

Using the following code (removed validation / logging for brevity):

        private static bool Verify(string contentFile, string signatureFile)
        {
            var contentBytes = File.ReadAllBytes(contentFile);
            var content = new CmsProcessableByteArray(contentBytes);
            var signatureBytes = File.ReadAllBytes(signatureFile);
            var cms = new CmsSignedData(content, signatureBytes);
            var certs = cms.GetCertificates("Collection");
            var signers = 
cms.GetSignerInfos().GetSigners().Cast<SignerInformation>().ToList();

            bool success = true;

            for (int i = 0; i < signers.Count; ++i)
            {
                var signer = signers[i];
                var cert = 
certs.GetMatches(signer.SignerID).Cast<X509Certificate>().Single();

                success &= signer.Verify(cert);
            }

            return success;
        }

Produces the following Exception:

Org.BouncyCastle.Security.SecurityUtilityException: Signer 
SHA256WITH0.4.0.127.0.7.1.1.4.1.3 not recognised.
   at Org.BouncyCastle.Security.SignerUtilities.GetSigner(String algorithm)
   at Org.BouncyCastle.Cms.SignerInformation.DoVerify(AsymmetricKeyParameter 
key)
   at Org.BouncyCastle.Cms.SignerInformation.Verify(X509Certificate cert)

It seems that this OID doesn’t just specify an encryption algorithm but a 
combination of encryption and digest algorithm and I can actually get a signer 
from SignerUtilities.GetSigner() when providing the above mentioned OID.

So I’ve also tried a different approach by replacing

                success &= signer.Verify(cert);

with

                var ecsigner = 
SignerUtilities.GetSigner("0.4.0.127.0.7.1.1.4.1.3");
                ecsigner.Init(false, cert.GetPublicKey());
                ecsigner.BlockUpdate(contentBytes, 0, contentBytes.Length);

                success &= ecsigner.VerifySignature(signer.GetSignature());

When using this approach, ecsigner.VerifySignature returns false, though.

Using .NET Framework 4.8 instead of .NET 5.0 produces the same result.

The Java version of BC can successfully verify this signature, but using that 
implementation is no longer an option.

What are we doing wrong?

Best regards
Alexander Sedlbauer

Reply via email to