Digital signature with C# and Json

Asked

Viewed 493 times

3

Good afternoon to you all. I’m using the link code https://github.com/Gread/BoletoOnlineBradesco that uses C# to sign Json and send the letters to Bradesco. My problem is occurring in Bouncy Castle’s class (http://www.bouncycastle.org/csharp/index.html), where I can’t retrieve the private key.

private void AssinarCriptografar(EnvioRemessaCobrancaBradescoJson model)
    {
        try
        {

            //exemplo validacao
            var validador = new ValidarModelo();
            var criticas = validador.Criticas(model);
            if (criticas.Any())
            {
                return;
            }

            var data = ConverterParaJsonAspasSimples(model);
            var encoding = new UTF8Encoding();
            var messageBytes = encoding.GetBytes(data);                

            var impressaDigitalCertificado = ConfigurationManager.AppSettings["ImpressaoDigitalCertificado"];

            // certificado precisa ser instalado na máquina local e na pasta pessoal, diferente disso alterar linha abaixo
            var store = new X509Store("My", StoreLocation.CurrentUser);

            store.Open(OpenFlags.ReadOnly);
            var privateCert = store.Certificates.Cast<X509Certificate2>().FirstOrDefault(cert => cert.Thumbprint == impressaDigitalCertificado && cert.HasPrivateKey);

            if (privateCert == null)                                    
                throw new Exception("Certificado não localizado.");                
            if (privateCert.PrivateKey == null)                
                throw new Exception("chave privada não localizada no certificado.");

            //convertendo certificado para objeto que o bouncycastle conhece
            var bouncyCastleKey = DotNetUtilities.GetKeyPair(privateCert.PrivateKey).Private;
            var x5091 = new X509Certificate(privateCert.RawData);
            var x509CertBouncyCastle = DotNetUtilities.FromX509Certificate(x5091);

            var generator = new CmsSignedDataGenerator();
            var signerInfoGeneratorBuilder = new SignerInfoGeneratorBuilder();
            generator.AddSignerInfoGenerator(
                signerInfoGeneratorBuilder.Build(new Asn1SignatureFactory("SHA256WithRSA", bouncyCastleKey),
                    x509CertBouncyCastle));

            //criando certstore que o bouncycastle conhece
            IList certList = new ArrayList();
            certList.Add(x509CertBouncyCastle);
            var store509BouncyCastle = X509StoreFactory.Create("Certificate/Collection", new X509CollectionStoreParameters(certList));
            generator.AddCertificates(store509BouncyCastle);

            var cmsdata = new CmsProcessableByteArray(messageBytes);
            //assina
            var signeddata = generator.Generate(cmsdata, true);
            var mensagemFinal = signeddata.GetEncoded();                
            //converte para base64 que eh o formato que o serviço espera
            var mensagemConvertidaparaBase64 = Convert.ToBase64String(mensagemFinal);                

            //chama serviço convertendo a string na base64 em bytes
            CriarServicoWebEEnviar("url_servico_bradesco_consta_manual", encoding.GetBytes(mensagemConvertidaparaBase64));
        }
        catch (Exception ex)
        {                
            throw;
        }
    }

When I call the function below it returns the error "{"Invalid key for use in the specified state. r n"}". var bouncyCastleKey = Dotnetutilities.Getkeypair(privateCert.Privatekey). Private;

Checking the Bouncy Castle code, the error occurs when it tries to send its parameters to the Getrsakeypair class ((RSA)privateKey) and then Getrsakeypair(rsa.Exportparameters(true))

public static AsymmetricCipherKeyPair GetKeyPair(AsymmetricAlgorithm privateKey)
    {
        if (privateKey is DSA)
        {
            return GetDsaKeyPair((DSA)privateKey);
        }

        if (privateKey is RSA)
        {
            return GetRsaKeyPair((RSA)privateKey);
        }

        throw new ArgumentException("Unsupported algorithm specified", "privateKey");
    }

public static AsymmetricCipherKeyPair GetRsaKeyPair(
        RSA rsa)
    {
        return GetRsaKeyPair(rsa.ExportParameters(true));
    }

When you try to pass the rsa parameter.Exportparameters as true, the error occurs, because as false it continues the process, but other errors occur later due to the lack of parameters.

I’m using Visual Studio 2010 with . NET Framework 4.0.0

I’m two weeks into this case, and I need to understand what’s going on. I thank everyone for their contribution.

  • If you are using a digital certificate of type "A1", you need to configure it during the installation saying that it will store the private key information, otherwise this error will probably occur. By default A1 does not do what I said...

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.