none
Autenticação Api rest json com certificado digital no cliente RRS feed

  • Question

  • Boa tarde Senhores,

    Venho aqui com uma enorme duvida de como me me autenticar com um certificado digital no Portal de um Cliente para envio de informações.

    A segurança do portal do cliente é baseada em SSL/TLS sendo obrigatório o uso do certificado tanto A1 e A3 do Padrão ICP-Brasil, é necessário o processo de handshake SSL entre minha aplicação e o Portal

    Fluxo de acionamento do serviço de autenticação:

    alt text

    Poderiam me ajudar com artigos ou me explicando como fazer?

    Desde já muito obrigado!

    Wednesday, August 23, 2017 4:47 PM

Answers

  • Olá Márcio,

    Você vai precisar criar uma classe que extenda a WebClient e anexar seu certificado :

    public class SecuretWebClient : System.Net.WebClient
        {
            System.Net.HttpWebRequest request = null;
            System.Security.Cryptography.X509Certificates.X509CertificateCollection certificates = null;
    
            protected override System.Net.WebRequest GetWebRequest(System.Uri address)
            {
                request = (System.Net.HttpWebRequest)base.GetWebRequest(address);
                if (certificates != null)
                {
                    request.ClientCertificates.AddRange(certificates);
                    request.PreAuthenticate = true;
                }
                return request;
            }
    
            public void AddCerts(System.Security.Cryptography.X509Certificates.X509Certificate[] certs)
            {
                if (certificates == null)
                {
                    certificates = new System.Security.Cryptography.X509Certificates.X509CertificateCollection();
                }
                if (request != null)
                {
                    request.ClientCertificates.AddRange(certs);
                }
                certificates.AddRange(certs);
            }
        }

    Uso:

    SecureWebClient client = new SecureWebClient();
                    client.Headers.Add("Content-type", "application/json");
    
                    client.AddCerts(new X509Certificate[] { SEU_CERTIFICADO });
    
                    result = client.UploadString("URL_API", JSON_ENTRADA);

    Outra dica pra ficar atento é ativar os TLS mais novos:

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;




    ​Rafael Esquiçato Professional Scrum Master MCP, MCTS

    Friday, August 25, 2017 3:17 AM

All replies

  • Boa tarde, Marcio Camargo. Tudo bem?

    Essa seria uma questão de "How to/Customização" ou "Break Fix/Erro"?

    Atenciosamente,

    Filipe B de Castro

    Esse conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita

    MSDN Community Support

    Por favor, lembre-se de Marcar como Resposta as postagens que resolveram o seu problema. Essa é uma maneira comum de reconhecer aqueles que o ajudaram e fazer com que seja mais fácil para os outros visitantes encontrarem a resolução mais tarde.

    Thursday, August 24, 2017 7:24 PM
    Moderator
  • Olá Márcio,

    Você vai precisar criar uma classe que extenda a WebClient e anexar seu certificado :

    public class SecuretWebClient : System.Net.WebClient
        {
            System.Net.HttpWebRequest request = null;
            System.Security.Cryptography.X509Certificates.X509CertificateCollection certificates = null;
    
            protected override System.Net.WebRequest GetWebRequest(System.Uri address)
            {
                request = (System.Net.HttpWebRequest)base.GetWebRequest(address);
                if (certificates != null)
                {
                    request.ClientCertificates.AddRange(certificates);
                    request.PreAuthenticate = true;
                }
                return request;
            }
    
            public void AddCerts(System.Security.Cryptography.X509Certificates.X509Certificate[] certs)
            {
                if (certificates == null)
                {
                    certificates = new System.Security.Cryptography.X509Certificates.X509CertificateCollection();
                }
                if (request != null)
                {
                    request.ClientCertificates.AddRange(certs);
                }
                certificates.AddRange(certs);
            }
        }

    Uso:

    SecureWebClient client = new SecureWebClient();
                    client.Headers.Add("Content-type", "application/json");
    
                    client.AddCerts(new X509Certificate[] { SEU_CERTIFICADO });
    
                    result = client.UploadString("URL_API", JSON_ENTRADA);

    Outra dica pra ficar atento é ativar os TLS mais novos:

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;




    ​Rafael Esquiçato Professional Scrum Master MCP, MCTS

    Friday, August 25, 2017 3:17 AM
  • Bom dia Rafael, 

    Muito obrigado pelo retorno e também pelo tempo em me ajudar!

    Só que eu fiquei com uma duvida 

    Aqui envio as informações

    result = client.UploadString("URL_API", JSON_ENTRADA);

    Como faço para ter o retorno?

    Desde já muito obrigado!

    Friday, August 25, 2017 2:04 PM
  • Márcio,

    O result no caso é uma string (falha minha não colocar o código todo), nele você terá o retorno. Como pelo que entendi é uma API REST, você terá provavelmente um JSON de retorno, aí só precisa desserializar para um objeto usando o JavaScriptSerializer do .NET ou o da NewtonSoft (JSON.NET) e ler os dados.


    ​Rafael Esquiçato Professional Scrum Master MCP, MCTS

    Friday, August 25, 2017 2:35 PM
  • Rafael,

    Então Fiz umas alterações para pegar os dados do meu certificado e enviar 

     //selecionarCertificado();
                SecuretWebClient client = new SecuretWebClient();
                client.Headers.Add("Content-type", "application/json");
    
                X509Certificate2 oCertificado;
                var oX509Cert = new X509Certificate2();
                var store = new X509Store("MY", StoreLocation.CurrentUser);
                store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                var collection = store.Certificates;
                var collection2 = collection.Find(X509FindType.FindByKeyUsage, X509KeyUsageFlags.DigitalSignature, false);
                var scollection = X509Certificate2UI.SelectFromCollection(collection2,
                  "Certificado(s) Digital(is) disponível(is)", "Selecione o certificado digital para uso no aplicativo",
                   X509SelectionFlag.SingleSelection);
                if (scollection.Count == 0)
                {
                    var msgResultado =
                        "Nenhum certificado digital foi selecionado ou o certificado selecionado está com problemas.";
                    MessageBox.Show(msgResultado, "Advertência", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else
                {
                    oX509Cert = scollection[0];
                    oCertificado = oX509Cert;
                    string txtNameCertDigital = oCertificado.IssuerName.Name;
                    long txtSerialCertDigital = oCertificado.Handle.ToInt64() ;
                    string txtValidadeCertDigital = oCertificado.NotBefore + " à " + oCertificado.NotAfter;
                    //string[] split = text.Split(new char[] { '>', '-' });
    
                    //Label2.Text = split[2];
                    string nome = oCertificado.Subject;
                    string[] split = nome.Split(new char[2] { '=', ',' });
                    string nomeCert = split[3];
    
    
                    DateTime oldDate = oCertificado.NotAfter;
                    DateTime newDate = DateTime.Now;
    
                    // Difference in days, hours, minutes, milleseconds.
                    TimeSpan ts = newDate - oldDate;
    
                    // Difference in days.
                    double differenceInDays = ts.TotalMilliseconds * -1;
    
    
                    client.AddCerts(new X509Certificate[] { scollection[0] });
    
                    string JSON_ENTRADA = "{'Role-Type':'IMPEXP','Set-Token': '" + oCertificado.SerialNumber + "','X-CSRF-Token':'" + oCertificado.NotAfter + "'}";
                    string result = client.UploadString("https://val.portalunico.siscomex.gov.br/portal/api/autenticar", JSON_ENTRADA);
    
                    //return result;
    
    
    
                }

    Até ai blz, executo ai gera um erro "A conexão subjacente estava fechada: Não foi possível estabelecer relação de confiança para o canal seguro de SSL/TLS."

    Obs. baixei e instalei as cadeias de certificados do site do Sepro

    Pelo que eu pesquisei, não estou enviando as informações necessárias para fechar uma conexão e pela documentação teria que enviar em regra de JWT esse Token poderá ser decodificado (Base64).

    Aqui está a documentação de autenticação https://val.portalunico.siscomex.gov.br/docs/api/#autentica-o

    Caso queira olhar, mesmo assim obrigado pelas dicas que já foram de grande ajuda!


    Friday, August 25, 2017 5:02 PM
  • Boa noite Márcio, 

    Conseguiu resolver esse problema? Estou passando pela mesma coisa e não encontrei uma solução ainda..

    Wednesday, September 20, 2017 1:50 AM
  • Bom dia Natassia,

    Não encontrei ainda estou parado no mesmo problema e você conseguiu avançar?

    Thursday, December 7, 2017 1:53 PM
  • Oi Natassia,

    Vc Conseguiu avançar?

    Wednesday, January 24, 2018 5:37 PM
  • Boa tarde, Marcio!

    Conseguiu avançar?

    Eu estou no mesmo ponto em que você estava neste último post, mas acho que peguei uma falha no seu código.

    No momento da autenticação, acho que você precisa enviar apenas o Role-Type *como header* em uma requisição autenticada pela sua chave. Daí é que você recebe o token JWT, para o Set-Token, e o X-CSRF-Token. Estes dois vão ser usados nas próximas requisições.

    Bate com a sua evolução?

    Abraço!

    Wednesday, February 28, 2018 8:05 PM
  • Marcio, teve algum progresso nesse caso?? Estou no mesmo problema e queria uma ajuda.
    Monday, January 16, 2023 2:17 PM