Как получить подписанную строку BouncyCastle в C #, чтобы быть точным, как в Java? - PullRequest
0 голосов
/ 26 сентября 2018

У меня есть сертификат .pfx, который следует использовать для цифровой подписи строковых сообщений.Есть рабочий пример, написанный на Java, который уже делает то, что ожидается, но наша среда основана на C # ...

Решение Java использует библиотеки Bouncy Castle, и оно очень похоже на пример документации класса CMSSignedDataGenerator , вот оно:

        final byte[] buf = stringData.getBytes("UTF-8");

        CMSTypedData typedData = new CMSProcessableByteArray(buf);
        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();

        ContentSigner signer = new JcaContentSignerBuilder(signatureAlgorithm).
                setProvider(ksProviderName).build(privateKey);

        JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(jcaDigestCalculatorProviderBuilder);
        gen.addSignerInfoGenerator(builder.build(signer, cert));
        CMSSignedData signed = gen.generate(typedData, false);
        byte[] der = signed.getEncoded();

        return Base64.getEncoder().encodeToString(der);

Существует реализация Bouncy Castle для C #, мы пытались ее использовать, но это не то же самое, что для Java, мы не смогли найти некоторые классы, которые соответствуют предыдущему кодуфрагмент (например, нам не удалось найти ни ContentSigner, ни JcaContentSignerBuilder).

        X509Certificate2 x509c2 = Cert.Instance.Certificate;

        byte[] buf = Encoding.UTF8.GetBytes(stringData);

        CmsProcessableByteArray typedData = new CmsProcessableByteArray(buf);
        CmsSignedDataGenerator gen = new CmsSignedDataGenerator();

        RSAParameters rsaParameters = ((RSACryptoServiceProvider)x509c2.PrivateKey).ExportParameters(true);

        AsymmetricKeyParameter keyParameters = new RsaKeyParameters(
            true,
            new BigInteger(1, rsaParameters.Modulus),
            new BigInteger(1, rsaParameters.Exponent)
            );

        Org.BouncyCastle.X509.X509Certificate bcCert = (new Org.BouncyCastle.X509.X509CertificateParser()).ReadCertificate(x509c2.RawData);
        Asn1SignatureFactory signatureFactory = new Asn1SignatureFactory(x509c2.SignatureAlgorithm.Value, keyParameters);

        SignerInfoGeneratorBuilder signerInfoGeneratorBuilder = new SignerInfoGeneratorBuilder();

        gen.AddSignerInfoGenerator(signerInfoGeneratorBuilder.Build(signatureFactory, bcCert));

        CmsSignedData signed = gen.Generate(typedData, false);

        byte[] signedBytes = signed.GetEncoded();

        return Convert.ToBase64String(signedBytes);

Возвращаемое значение (подпись в кодировке base64) не соответствует ни одному из кода Java.Подпись из Java возвращает строку длиной 820 символов, в то время как из этого кода C # мы получаем 756 символов («мы так близки», - говорит мой коллега: -))

Любая помощь, чтобы получить соответствующий результат?

...