Jump to content

Utilizar Webservices da AT


cjulio
Go to solution Solved by thoga31,

Recommended Posts

Em 13/11/2022 às 22:06, Pedro Alves disse:

Boas,

É a primeira vez que vou integrar com a AT, pediram-me para consumir o webservice para comunicação das séries documentais.

Estive a ler a documentação e no documento "Comunicação de Séries Documentais, Aspetos Genéricos" segui os requisitos para o SOAP header.

Eis o que fiz hoje (com muita, mesmo muita pesquisa), isto está ok? 🤔

	internal class SoapHeader
    {
        private string _pathCertificado = @".\certs\TesteWebservices.pfx";
        private X509Certificate2 cert;
        private PublicKey publicKey;
        private byte[] chaveSimetrica;
        private string nonce = string.Empty;
        private string encryptedPassword = string.Empty;
        private string encryptedDataCreated = string.Empty;

        public SoapHeader()
        {
            cert = new X509Certificate2(_pathCertificado, "TESTEwebservice");
            publicKey = cert.PublicKey;
            
            chaveSimetrica = CreateSymmetricKey();
             
            nonce = Convert.ToBase64String(EncryptSymmetricKey(chaveSimetrica));
            encryptedPassword = Convert.ToBase64String(EncryptDataWithSymmetricKey("MinhaPassword"));
            encryptedDataCreated = Convert.ToBase64String(EncryptDataWithSymmetricKey(GetDataCreated()));
           	Console.WriteLine("Username: {0}", "999999999/1");
            Console.WriteLine("Nonce: {0}", nonce);
            Console.WriteLine("Password: {0}", encryptedPassword);
            Console.WriteLine("Data Created: {0}", encryptedDataCreated);

        }

        private byte[] CreateSymmetricKey()
        {
            using (var aes = Aes.Create())
            {
                aes.KeySize = 128;
                aes.BlockSize = 128;
                aes.Padding = PaddingMode.PKCS7;
                aes.Mode = CipherMode.ECB;
                aes.GenerateIV();
                aes.GenerateKey();

                return aes.Key;
            }
        }

        private byte[] EncryptSymmetricKey(byte[] input)
        {
            byte[] result;
            using (var rsa = RSA.Create())
            {
                rsa.ImportRSAPublicKey(cert.GetRSAPublicKey()?.ExportRSAPublicKey(), out _);
                result = rsa.Encrypt(input, RSAEncryptionPadding.Pkcs1);                
            }
            return result;
        }

        private byte[] EncryptDataWithSymmetricKey(string input)
        {
            byte[] result;
            byte[] data = Encoding.UTF8.GetBytes(input);
            using (var aes = Aes.Create())
            {
                aes.Key = chaveSimetrica;
                result = aes.EncryptEcb(data, PaddingMode.PKCS7);
            }
            return result;
        }

        private string GetDataCreated()
        {
            NtpClient client = new NtpClient("ntp02.oal.ul.pt");
            NtpClock clock = client.Query();

            return clock.Now.ToString("yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture);
        }
    }

 

Já experimentaste comunicar?

Link to comment
Share on other sites

Em 14/11/2022 às 15:50, Vitor Pereira disse:

Nuno, acabei de comunicar uma agora mesmo e sem problemas 

É, já descobri o problema.
A mensagem de erro, a existir, seria

Citação

User error. Replace user and press any key to continue.


Enviei um mail a toda a gente a pedir que criassem um utilizador para a comunicação de séries, para adiantar serviço quando as SH do software que vendo me disponibilizarem as versões com ATCUD.
Enviei até um passo a passo de como aceder ao portal e criar um utilizador, com screenshots e tudo.
Este cliente em particular (ou alguém por ele) achou que o melhor mesmo era editar o utilizador existente (dos documentos de transporte), remover o pisco do WDT e adicionar o pisco ao WSE.

Why, oh why, are people so d..b?

É como aquele meme:
- Seguir o passo-a-passo? Nahhhh!

- Mexer no que está quieto? Yeahhhh!
 

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

On 11/15/2022 at 10:49 AM, Nuno.Massa said:

Bom dia,

Alguém me consegue confirmar no caso do webservice de comunicação de faturas tem algum limite de pedidos por segundo?

Se vai dar para mandar mais que um documento por pedido?

Não. É em fila indiana... 😄

The simplest explanation is usually the correct one

JAVA Utilities: https://github.com/marcolopes/dma

Link to comment
Share on other sites

Em 15/11/2022 às 12:52, marcolopes disse:

Não. É em fila indiana... 😄

Ou como se diz na minha terra, "filinha pirilau" 

😂

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

Em 14/11/2022 às 13:47, Pedro Alves disse:

Lol, ainda não, por esse motivo estar já a perguntar se isto vai funcionar quando o fizer. Mas durante esta semana já conto conseguir.

Não sei muito bem como é que isto do SOAP funciona em c#.

Obrigado.

Estou a usar .net core 7 e estou neste ponto (nota o username e password estão com XXXXXX por questões de privacidade, estou a usar as credenciais corretas 🙂)

Estou a receber o seguinte erro:

System.ServiceModel.Security.SecurityNegotiationException: 'Could not establish trust relationship for the SSL/TLS secure channel with authority 'servicos.portaldasfinancas.gov.pt:722'.'

O meu código:

 static void Main(string[] args)
        {
            string _pathCertificado = @".\certs\TesteWebservices.pfx";
            string _chavePublica = @".\certs\ChaveCifraPublicaAT2023.cer";
            X509Certificate2 certificado = new X509Certificate2(_pathCertificado, "TESTEwebservice");
            X509Certificate2 chavePublica = new X509Certificate2(_chavePublica);

            var username = "XXXXXXXXX/X";
            var password = "XXXXXXX";
            ATMessageHeaderSecurity security = new ATMessageHeaderSecurity(password, certificado, chavePublica);

            var endpointAddress = "https://servicos.portaldasfinancas.gov.pt:722/SeriesWSService";

            BasicHttpsBinding binding = new BasicHttpsBinding();
            binding.Security.Mode = BasicHttpsSecurityMode.Transport;
            EndpointAddress endpoint = new EndpointAddress(new Uri(endpointAddress));
            SeriesWSClient client = new SeriesWSClient(binding, endpoint);

            client.Endpoint.EndpointBehaviors.Add(new Log4NetAuditBehavior());
            using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
            {
                ServicePointManager.SecurityProtocol = 
                    SecurityProtocolType.Tls |
                    SecurityProtocolType.Tls11 |
                    SecurityProtocolType.Tls12 | 
                    SecurityProtocolType.Tls13;

                OperationContext.Current.OutgoingMessageHeaders.Add(
                    new UsernameSecurityToken(username, security.encryptedPassword, security.nonce, security.encryptedDataCreated));

                var response = client.registarSerie("00001", "F", "SI", "FT", "1", DateTime.Now, "2000", "PI");
            }

        }

A mensagem que estou a gerar é 

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
	<s:Header>
		<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://at.gov.pt/SeriesWS/registarSerieRequest</Action>
		<wss:Security xmlns:wss="https://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:at="http://at.pt/wsp/auth" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
			<wss:UsernameToken>
				<wss:Username>XXXXXXXXX/X</wss:Username>
              	<wss:Password>EG1t6Fyzsr8MMAk4oA1OKA==</wss:Password>
              <wss:Nonce>mneEK20Hy2Tkg3TUKmDgKvcKu/rHgg356Ja1AroEbk6yAS2TFYijDgtFEpgPKJmqOZJW0Vl6BCQZLaz3h0sg1oYzupb97HngUoRHIsRgjkBRtZEpcVBIk1zAVfmWwHXeFVwTtVwgj0GSSCElZHfY154k90bVvkGADQn3kP04ypBFNr5dCat9qsf8XIFSltTrPZCVH9cV8QOPrD1qcCiRnSjrySdzwA7HutsiLT5toQkoKJnRvFi2h9Rv0lMLGn8ebmuE1NUUFPK6nuj2Rvo1Zj5WATo3nbwrY5qZFdkyTaZq+oyKQ+J/CFqZfCXGuHaSor7bRKhTBqdI75UKAIu79g==</wss:Nonce>
				<wss:Created>VDf0m0DRu9VQGO8oq/IMSArc/GGb4I8nIIllA3UGMMM=</wss:Created>
			</wss:UsernameToken>
		</wss:Security>
	</s:Header>
	<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
		<registarSerie xmlns="http://at.gov.pt/">
			<serie xmlns="">00001</serie>
			<tipoSerie xmlns="">F</tipoSerie>
			<classeDoc xmlns="">SI</classeDoc>
			<tipoDoc xmlns="">FT</tipoDoc>
			<numInicialSeq xmlns="">1</numInicialSeq>
			<dataInicioPrevUtiliz xmlns="">2022-11-16</dataInicioPrevUtiliz>
			<numCertSWFatur xmlns="">2000</numCertSWFatur>
			<meioProcessamento xmlns="">PI</meioProcessamento>
		</registarSerie>
	</s:Body>
</s:Envelope>

Alguma ideia do que posso estar a fazer de errado?

Obrigado pela ajuda.

Edited by Pedro Alves
Link to comment
Share on other sites

Em 16/11/2022 às 16:10, Pedro Alves disse:

Estou a usar .net core 7 e estou neste ponto (nota o username e password estão com XXXXXX por questões de privacidade, estou a usar as credenciais corretas 🙂)

Estou a receber o seguinte erro:

System.ServiceModel.Security.SecurityNegotiationException: 'Could not establish trust relationship for the SSL/TLS secure channel with authority 'servicos.portaldasfinancas.gov.pt:722'.'

O meu código:

 static void Main(string[] args)
        {
            string _pathCertificado = @".\certs\TesteWebservices.pfx";
            string _chavePublica = @".\certs\ChaveCifraPublicaAT2023.cer";
            X509Certificate2 certificado = new X509Certificate2(_pathCertificado, "TESTEwebservice");
            X509Certificate2 chavePublica = new X509Certificate2(_chavePublica);

            var username = "XXXXXXXXX/X";
            var password = "XXXXXXX";
            ATMessageHeaderSecurity security = new ATMessageHeaderSecurity(password, certificado, chavePublica);

            var endpointAddress = "https://servicos.portaldasfinancas.gov.pt:722/SeriesWSService";

            BasicHttpsBinding binding = new BasicHttpsBinding();
            binding.Security.Mode = BasicHttpsSecurityMode.Transport;
            EndpointAddress endpoint = new EndpointAddress(new Uri(endpointAddress));
            SeriesWSClient client = new SeriesWSClient(binding, endpoint);

            client.Endpoint.EndpointBehaviors.Add(new Log4NetAuditBehavior());
            using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
            {
                ServicePointManager.SecurityProtocol = 
                    SecurityProtocolType.Tls |
                    SecurityProtocolType.Tls11 |
                    SecurityProtocolType.Tls12 | 
                    SecurityProtocolType.Tls13;

                OperationContext.Current.OutgoingMessageHeaders.Add(
                    new UsernameSecurityToken(username, security.encryptedPassword, security.nonce, security.encryptedDataCreated));

                var response = client.registarSerie("00001", "F", "SI", "FT", "1", DateTime.Now, "2000", "PI");
            }

        }

A mensagem que estou a gerar é 

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
	<s:Header>
		<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://at.gov.pt/SeriesWS/registarSerieRequest</Action>
		<wss:Security xmlns:wss="https://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:at="http://at.pt/wsp/auth" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
			<wss:UsernameToken>
				<wss:Username>XXXXXXXXX/X</wss:Username>
              	<wss:Password>EG1t6Fyzsr8MMAk4oA1OKA==</wss:Password>
              <wss:Nonce>mneEK20Hy2Tkg3TUKmDgKvcKu/rHgg356Ja1AroEbk6yAS2TFYijDgtFEpgPKJmqOZJW0Vl6BCQZLaz3h0sg1oYzupb97HngUoRHIsRgjkBRtZEpcVBIk1zAVfmWwHXeFVwTtVwgj0GSSCElZHfY154k90bVvkGADQn3kP04ypBFNr5dCat9qsf8XIFSltTrPZCVH9cV8QOPrD1qcCiRnSjrySdzwA7HutsiLT5toQkoKJnRvFi2h9Rv0lMLGn8ebmuE1NUUFPK6nuj2Rvo1Zj5WATo3nbwrY5qZFdkyTaZq+oyKQ+J/CFqZfCXGuHaSor7bRKhTBqdI75UKAIu79g==</wss:Nonce>
				<wss:Created>VDf0m0DRu9VQGO8oq/IMSArc/GGb4I8nIIllA3UGMMM=</wss:Created>
			</wss:UsernameToken>
		</wss:Security>
	</s:Header>
	<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
		<registarSerie xmlns="http://at.gov.pt/">
			<serie xmlns="">00001</serie>
			<tipoSerie xmlns="">F</tipoSerie>
			<classeDoc xmlns="">SI</classeDoc>
			<tipoDoc xmlns="">FT</tipoDoc>
			<numInicialSeq xmlns="">1</numInicialSeq>
			<dataInicioPrevUtiliz xmlns="">2022-11-16</dataInicioPrevUtiliz>
			<numCertSWFatur xmlns="">2000</numCertSWFatur>
			<meioProcessamento xmlns="">PI</meioProcessamento>
		</registarSerie>
	</s:Body>
</s:Envelope>

Alguma ideia do que posso estar a fazer de errado?

Obrigado pela ajuda.

Penso que tem a ver com o certificado

Link to comment
Share on other sites

Em 16/11/2022 às 16:10, Pedro Alves disse:

Estou a usar .net core 7 e estou neste ponto (nota o username e password estão com XXXXXX por questões de privacidade, estou a usar as credenciais corretas 🙂)

Estou a receber o seguinte erro:

System.ServiceModel.Security.SecurityNegotiationException: 'Could not establish trust relationship for the SSL/TLS secure channel with authority 'servicos.portaldasfinancas.gov.pt:722'.'

O meu código:

A mensagem que estou a gerar é 

Alguma ideia do que posso estar a fazer de errado?

Obrigado pela ajuda.

Deve ser a validação do certificado que está a falhar. Muitos de nós escolhem ignorar a validação - tem que ser feito de forma explícita - ou então validar por ex. que o hash do certificado do outro lado é o esperado, que é como quem diz ter a certeza que estás a falar com os servidores da AT.

Em .NET Standard 2.0 podes ter algo como:

            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceEndpoint);
                request.ServerCertificateValidationCallback = f;
                request.ClientCertificates.Add(privateCertificate);
...
              }
            catch (Exception ex)
            {
                return ...
            }

            bool f(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                string hash = certificate.GetCertHashString();
                return hash == "170B4A083FBF8BBB88268B7AAB433510AB453320";
            }

Neste exemplo, a função f valida que o hash do certificado do servidor da AT é o esperado - basta abrir o certificado que a AT atualiza anualmente e ver o respetivo hash - mas há quem simplesmente devolva incondicionalmente true, ignorando a validação.

Link to comment
Share on other sites

Em 16/11/2022 às 16:33, albertosilva disse:

Deve ser a validação do certificado que está a falhar. Muitos de nós escolhem ignorar a validação - tem que ser feito de forma explícita - ou então validar por ex. que o hash do certificado do outro lado é o esperado, que é como quem diz ter a certeza que estás a falar com os servidores da AT.

Em .NET Standard 2.0 podes ter algo como:

            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceEndpoint);
                request.ServerCertificateValidationCallback = f;
                request.ClientCertificates.Add(privateCertificate);
...
              }
            catch (Exception ex)
            {
                return ...
            }

            bool f(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                string hash = certificate.GetCertHashString();
                return hash == "170B4A083FBF8BBB88268B7AAB433510AB453320";
            }

Neste exemplo, a função f valida que o hash do certificado do servidor da AT é o esperado - basta abrir o certificado que a AT atualiza anualmente e ver o respetivo hash - mas há quem simplesmente devolva incondicionalmente true, ignorando a validação.

Pois é mesmo isso, estou a obter o seguinte:

ATCUD\bin\Debug\net7.0\certs>openssl s_client -connect servicos.portaldasfinancas.gov.pt:722
CONNECTED(000001C0)
depth=1 C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = PT, L = Lisboa, O = Autoridade Tribut\C3\A1ria e Aduaneira, CN = *.portaldasfinancas.gov.pt
verify return:1
31952:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:ssl\record\rec_layer_s3.c:1544:SSL alert number 40
---
Certificate chain
 0 s:C = PT, L = Lisboa, O = Autoridade Tribut\C3\A1ria e Aduaneira, CN = *.portaldasfinancas.gov.pt
   i:C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1
 1 s:C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1
   i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGxzCCBa+gAwIBAgIQBFKU/ajbj9JDCNgGqIKDQDANBgkqhkiG9w0BAQsFADBP
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSkwJwYDVQQDEyBE
aWdpQ2VydCBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTAeFw0yMjAzMTYwMDAwMDBa
Fw0yMzAzMTYyMzU5NTlaMHAxCzAJBgNVBAYTAlBUMQ8wDQYDVQQHEwZMaXNib2Ex
KzApBgNVBAoMIkF1dG9yaWRhZGUgVHJpYnV0w6FyaWEgZSBBZHVhbmVpcmExIzAh
BgNVBAMMGioucG9ydGFsZGFzZmluYW5jYXMuZ292LnB0MIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAzwC5bHosmvWuNew03VFCybzpsXPoX2iwj4mYhiRD
qxdEb5I7uEdMf4ctBDaeaEG4hNseVhxijVWFfwyR8gKpcX2Ry1mrxvPhG792H4tH
RihZJ2ktrP+ksfpWYDqQoHjndBdnoio7DjwIZRABLqkunhMCjImiigzdPp+0U1BA
3Tra0er+BloxVflrnmjl/LJN0ipiCqN41VE5uoQjIbGkqeo8njevW/6hY6BwikgS
Ji6NsvzviWZmd8eXdjLYd/UqIZP7QhphNY5HVWrDRlZAigStRRa01QbneiXcZKfL
b2RXsDLRbro0td5qD0BBbMtkrz9/df6fql7g2itMAH2gSwIDAQABo4IDfDCCA3gw
HwYDVR0jBBgwFoAUt2ui6qiqhIx56rTaD5iyxZV2ufQwHQYDVR0OBBYEFJGueMK6
apo+8ayPQWD8WU/2jey9MCUGA1UdEQQeMByCGioucG9ydGFsZGFzZmluYW5jYXMu
Z292LnB0MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB
BQUHAwIwgY8GA1UdHwSBhzCBhDBAoD6gPIY6aHR0cDovL2NybDMuZGlnaWNlcnQu
Y29tL0RpZ2lDZXJ0VExTUlNBU0hBMjU2MjAyMENBMS00LmNybDBAoD6gPIY6aHR0
cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VExTUlNBU0hBMjU2MjAyMENB
MS00LmNybDA+BgNVHSAENzA1MDMGBmeBDAECAjApMCcGCCsGAQUFBwIBFhtodHRw
Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwfwYIKwYBBQUHAQEEczBxMCQGCCsGAQUF
BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wSQYIKwYBBQUHMAKGPWh0dHA6
Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRMU1JTQVNIQTI1NjIwMjBD
QTEtMS5jcnQwCQYDVR0TBAIwADCCAYAGCisGAQQB1nkCBAIEggFwBIIBbAFqAHcA
6D7Q2j71BjUy51covIlryQPTy9ERa+zraeF3fW0GvW4AAAF/kmE9EwAABAMASDBG
AiEA07WdnZI35VGuzwLXiSb0T7D91+qBEOULMU8XfMabwpECIQCZSM5kdjul5XlW
zxDqt2ngP60vBlMh67pxhpOCPGMeYQB2ADXPGRu/sWxXvw+tTG1Cy7u2JyAmUeo/
4SrvqAPDO9ZMAAABf5JhPU8AAAQDAEcwRQIhAPAeqEWrifA5X4voWKXSbufiKcO6
OBGtchsOUazdQatrAiBGt7Bc/N/GnBN2xYqumhXu9kKEGgUD5d5tUU99fLpt3gB3
ALNzdwfhhFD4Y4bWBancEQlKeS2xZwwLh9zwAw55NqWaAAABf5JhPX8AAAQDAEgw
RgIhAJw4e6eUH0s+y8ha6rV5/6FP56YyIYpZGGMXargaVmx7AiEAwJC5nQvtxVz/
kyk58i1FEugZ2t3UyQWXhJ1X6+tX904wDQYJKoZIhvcNAQELBQADggEBAGOWP3WM
+5AqgSzA68Vc9gBbJmsH10Di1fxIqAq7Py4GwEp8hYQCJAsc6HC32YhsMPodIXSN
YAqLwr/Eyb08aUOOyBRE+CP0P0ICL9QudUn5QuH7PU/zhokTJxfYFQxLGOlIsOnt
KPkerhKPMMp/Fj8jEdX4IOOtgaQMc/UIjLDNgPmVpsmLOXHPrRTMNGHCC+z6PAT4
EO49yI09ciMgNThGt5aoP4gDl7WCttp6HqNJgObOyk9DuZCYuyGEZ5YTBLcFMHWn
5rETCBrpYRZifWVKtAQcBWooGWj7PkppZV84vOrFYa3vL/S4uBglxZB7+5qvwZeP
9MzQlJDVBZPSn/g=
-----END CERTIFICATE-----
subject=C = PT, L = Lisboa, O = Autoridade Tribut\C3\A1ria e Aduaneira, CN = *.portaldasfinancas.gov.pt

issuer=C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1

---
Acceptable client certificate CA names
C = PT, L = Lisboa, O = Autoridade Tributaria e Aduaneira, CN = AT Issuing CA1
DC = local, DC = ritta, CN = DGITA Issuing CA1
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256
Shared Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256
Peer signing digest: SHA512
Peer signature type: RSA
Server Temp Key: ECDH, P-384, 384 bits
---
SSL handshake has read 3639 bytes and written 505 bytes
Verification error: unable to get local issuer certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID:
    Session-ID-ctx:
    Master-Key: 81B0E4753F67905CF5DAB8AB5616B57CC0343C63BB625A6BBAFAFEC2189744907D4B4191D1C2AE09652C1956C514997C
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1668617312
    Timeout   : 7200 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
    Extended master secret: yes
---

Link to comment
Share on other sites

Em 16/11/2022 às 16:51, Pedro Alves disse:

Pois é mesmo isso, estou a obter o seguinte:

ATCUD\bin\Debug\net7.0\certs>openssl s_client -connect servicos.portaldasfinancas.gov.pt:722
CONNECTED(000001C0)
depth=1 C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = PT, L = Lisboa, O = Autoridade Tribut\C3\A1ria e Aduaneira, CN = *.portaldasfinancas.gov.pt
verify return:1
31952:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:ssl\record\rec_layer_s3.c:1544:SSL alert number 40
---
Certificate chain
 0 s:C = PT, L = Lisboa, O = Autoridade Tribut\C3\A1ria e Aduaneira, CN = *.portaldasfinancas.gov.pt
   i:C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1
 1 s:C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1
   i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGxzCCBa+gAwIBAgIQBFKU/ajbj9JDCNgGqIKDQDANBgkqhkiG9w0BAQsFADBP
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSkwJwYDVQQDEyBE
aWdpQ2VydCBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTAeFw0yMjAzMTYwMDAwMDBa
Fw0yMzAzMTYyMzU5NTlaMHAxCzAJBgNVBAYTAlBUMQ8wDQYDVQQHEwZMaXNib2Ex
KzApBgNVBAoMIkF1dG9yaWRhZGUgVHJpYnV0w6FyaWEgZSBBZHVhbmVpcmExIzAh
BgNVBAMMGioucG9ydGFsZGFzZmluYW5jYXMuZ292LnB0MIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAzwC5bHosmvWuNew03VFCybzpsXPoX2iwj4mYhiRD
qxdEb5I7uEdMf4ctBDaeaEG4hNseVhxijVWFfwyR8gKpcX2Ry1mrxvPhG792H4tH
RihZJ2ktrP+ksfpWYDqQoHjndBdnoio7DjwIZRABLqkunhMCjImiigzdPp+0U1BA
3Tra0er+BloxVflrnmjl/LJN0ipiCqN41VE5uoQjIbGkqeo8njevW/6hY6BwikgS
Ji6NsvzviWZmd8eXdjLYd/UqIZP7QhphNY5HVWrDRlZAigStRRa01QbneiXcZKfL
b2RXsDLRbro0td5qD0BBbMtkrz9/df6fql7g2itMAH2gSwIDAQABo4IDfDCCA3gw
HwYDVR0jBBgwFoAUt2ui6qiqhIx56rTaD5iyxZV2ufQwHQYDVR0OBBYEFJGueMK6
apo+8ayPQWD8WU/2jey9MCUGA1UdEQQeMByCGioucG9ydGFsZGFzZmluYW5jYXMu
Z292LnB0MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB
BQUHAwIwgY8GA1UdHwSBhzCBhDBAoD6gPIY6aHR0cDovL2NybDMuZGlnaWNlcnQu
Y29tL0RpZ2lDZXJ0VExTUlNBU0hBMjU2MjAyMENBMS00LmNybDBAoD6gPIY6aHR0
cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VExTUlNBU0hBMjU2MjAyMENB
MS00LmNybDA+BgNVHSAENzA1MDMGBmeBDAECAjApMCcGCCsGAQUFBwIBFhtodHRw
Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwfwYIKwYBBQUHAQEEczBxMCQGCCsGAQUF
BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wSQYIKwYBBQUHMAKGPWh0dHA6
Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRMU1JTQVNIQTI1NjIwMjBD
QTEtMS5jcnQwCQYDVR0TBAIwADCCAYAGCisGAQQB1nkCBAIEggFwBIIBbAFqAHcA
6D7Q2j71BjUy51covIlryQPTy9ERa+zraeF3fW0GvW4AAAF/kmE9EwAABAMASDBG
AiEA07WdnZI35VGuzwLXiSb0T7D91+qBEOULMU8XfMabwpECIQCZSM5kdjul5XlW
zxDqt2ngP60vBlMh67pxhpOCPGMeYQB2ADXPGRu/sWxXvw+tTG1Cy7u2JyAmUeo/
4SrvqAPDO9ZMAAABf5JhPU8AAAQDAEcwRQIhAPAeqEWrifA5X4voWKXSbufiKcO6
OBGtchsOUazdQatrAiBGt7Bc/N/GnBN2xYqumhXu9kKEGgUD5d5tUU99fLpt3gB3
ALNzdwfhhFD4Y4bWBancEQlKeS2xZwwLh9zwAw55NqWaAAABf5JhPX8AAAQDAEgw
RgIhAJw4e6eUH0s+y8ha6rV5/6FP56YyIYpZGGMXargaVmx7AiEAwJC5nQvtxVz/
kyk58i1FEugZ2t3UyQWXhJ1X6+tX904wDQYJKoZIhvcNAQELBQADggEBAGOWP3WM
+5AqgSzA68Vc9gBbJmsH10Di1fxIqAq7Py4GwEp8hYQCJAsc6HC32YhsMPodIXSN
YAqLwr/Eyb08aUOOyBRE+CP0P0ICL9QudUn5QuH7PU/zhokTJxfYFQxLGOlIsOnt
KPkerhKPMMp/Fj8jEdX4IOOtgaQMc/UIjLDNgPmVpsmLOXHPrRTMNGHCC+z6PAT4
EO49yI09ciMgNThGt5aoP4gDl7WCttp6HqNJgObOyk9DuZCYuyGEZ5YTBLcFMHWn
5rETCBrpYRZifWVKtAQcBWooGWj7PkppZV84vOrFYa3vL/S4uBglxZB7+5qvwZeP
9MzQlJDVBZPSn/g=
-----END CERTIFICATE-----
subject=C = PT, L = Lisboa, O = Autoridade Tribut\C3\A1ria e Aduaneira, CN = *.portaldasfinancas.gov.pt

issuer=C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1

---
Acceptable client certificate CA names
C = PT, L = Lisboa, O = Autoridade Tributaria e Aduaneira, CN = AT Issuing CA1
DC = local, DC = ritta, CN = DGITA Issuing CA1
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256
Shared Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256
Peer signing digest: SHA512
Peer signature type: RSA
Server Temp Key: ECDH, P-384, 384 bits
---
SSL handshake has read 3639 bytes and written 505 bytes
Verification error: unable to get local issuer certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID:
    Session-ID-ctx:
    Master-Key: 81B0E4753F67905CF5DAB8AB5616B57CC0343C63BB625A6BBAFAFEC2189744907D4B4191D1C2AE09652C1956C514997C
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1668617312
    Timeout   : 7200 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
    Extended master secret: yes
---

Desculpem a minha pergunta, preciso fazer mais alguma com os ficheiros .pfx e .cer que a AT me enviou?

Esqueci referir que estou com Windows 11...se é que é importante

Edited by Pedro Alves
Link to comment
Share on other sites

Em 16/11/2022 às 16:51, Pedro Alves disse:

Pois é mesmo isso, estou a obter o seguinte:

ATCUD\bin\Debug\net7.0\certs>openssl s_client -connect servicos.portaldasfinancas.gov.pt:722
CONNECTED(000001C0)
depth=1 C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = PT, L = Lisboa, O = Autoridade Tribut\C3\A1ria e Aduaneira, CN = *.portaldasfinancas.gov.pt
verify return:1
31952:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:ssl\record\rec_layer_s3.c:1544:SSL alert number 40
---
...

Num projeto .NET Core 6, para "falar" com um servidor com um certificado não emitido por uma CA reconhecida, temos que acrescentar a primeira que destaquei, enquanto que a última linha é a que ignora a validação do certificado. Atenção, este exemplo não tem nada a ver com comunicação à AT.

                _cookieContainer = new CookieContainer();
                HttpClientHandler handler = new HttpClientHandler()
                {
                    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
                    CookieContainer = _cookieContainer,
                    UseCookies = true
                };
#if NETCOREAPP3_1
                handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
#endif
                __client = new HttpClient(handler) { BaseAddress = this.BaseAddress };
                __client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                __client.DefaultRequestHeaders.ExpectContinue = false;
                __client.Timeout = TimeSpan.FromMinutes(_serviceTimeoutMinutes);
                ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
 

Link to comment
Share on other sites

Em 16/11/2022 às 16:58, albertosilva disse:

Num projeto .NET Core 6, para "falar" com um servidor com um certificado não emitido por uma CA reconhecida, temos que acrescentar a primeira que destaquei, enquanto que a última linha é a que ignora a validação do certificado. Atenção, este exemplo não tem nada a ver com comunicação à AT.

                _cookieContainer = new CookieContainer();
                HttpClientHandler handler = new HttpClientHandler()
                {
                    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
                    CookieContainer = _cookieContainer,
                    UseCookies = true
                };
#if NETCOREAPP3_1
                handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
#endif
                __client = new HttpClient(handler) { BaseAddress = this.BaseAddress };
                __client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                __client.DefaultRequestHeaders.ExpectContinue = false;
                __client.Timeout = TimeSpan.FromMinutes(_serviceTimeoutMinutes);
                ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
 

Certo, mas eu já nem me refiro a código, o que eu quero primeiro entender é se quando executam o seguinte: openssl s_client -connect servicos.portaldasfinancas.gov.pt:722 , se também estão a receber o erro 31952:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:ssl\record\rec_layer_s3.c:1544:SSL alert number 40.

Este erro está na origem da minha impossibilidade de comunicar com a AT (via código) ou não está relacionado e tenho de contornar o problema via código?

Obrigado.

Edited by Pedro Alves
Link to comment
Share on other sites

Em 17/11/2022 às 09:55, Pedro Alves disse:

Certo, mas eu já nem me refiro a código, o que eu quero primeiro entender é se quando executam o seguinte: openssl s_client -connect servicos.portaldasfinancas.gov.pt:722 , se também estão a receber o erro 31952:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:ssl\record\rec_layer_s3.c:1544:SSL alert number 40.

Este erro está na origem da minha impossibilidade de comunicar com a AT (via código) ou não está relacionado e tenho de contornar o problema via código?

Obrigado.

Eu não fiz em .NET mas ou ignoras o erro ou tens de instalar os 3 certificados da AT.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.