Usuário com melhor resposta
sobre ssl

Pergunta
-
boas pessoal
estou a tentar fazer uma aplicação que consiste no seguinte:
tenho uma aplicação servidora em c#, e queria que comunicasse com os respectivos clientes via ssl, no entanto tenho tido problemas com os certificados, visto que sempre que um cliente se liga, o servidor dá o seguinte erro "o certificado do servidor tem que ter uma chave privada associada".
Penso que ainda não consegui perceber como funciona o ssl, se alguem poder ajudar, agradecia.
obrigado
Respostas
Todas as Respostas
-
-
-
Mauro,
Seu post não deixa claro para mim em que ponto você está. Para tentar responder sua questão vou partir de algumas coisas que acho que você já fez:
1-Seu site no servidor web (IIS, por exemplo) já está configurado com um certificado de servidor.
2-Quando você vai acessar o site (um método web, por exemplo) pelo browse, você recebe um aviso indicando que não é possível avaliar se o site é quem diz ser, que o endereço do site não é o mesmo do certificado ou então que a data de validade do certificado expirou.
É isso?
Sendo este o caso, em aplicações WEB isto não tem problema pois a exceção é convertida nesta mensagem que o usuário pode manipular. Em aplicativos windows (como é o seu caso) você precisa (se for mesmo esta a intenção) 'tratar' esta validação. O exemplo abaixo (Framework 2.0) trata a questão do site com nome diferente daquele definido no certificado e trata também o fato da parte cliente do certificado não ter sido distribuída.
System.Net.ServicePointManager.ServerCertificateValidationCallback =
new System.Net.Security.RemoteCertificateValidationCallback(this.RemoteCertificateValidationCallback);private bool RemoteCertificateValidationCallback(
Object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
{
//Se a questão for que o certificado não está
//no cliente, deixo passar!
if (chain.ChainStatus != null &&
chain.ChainStatus.Length == 1 &&
(chain.ChainStatus[0].Status & X509ChainStatusFlags.PartialChain) != 0)
{
return true;
}
}
else
{
//Se a questão for apenas o nome do site a qual o certificado é dedicado,
//então deixo passar...
if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNameMismatch)
return true;
}
return false;
}Espero ter ajudado!
Marcelo Palladino
-
Cara estou tendo este tipo de problema, coloquei o código que você postou la porem não estou sabendo como fazer achamada dele... faço isso quando estiver fazer o WebRequest? e como pego o certificado, chain e etc..? não mexi muito ainda com esse tipo de post.. se puder ajudar..
-
-
A situação é a seguinte cara.. eu estou gerando uma classe através de um wsdl.. então depois de gerada é solicitado que se faça algumas alterações dai ele me pede para criar essa linha: System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();
que de acordo com o visual studio é uma classe que já não se usa mais.. e pede para usar essa que foi postada acima.. porém não estou sabendo como implementa-la corretamente... de uma olhada no que é pedido pelo read-me.
1. Run WSDL.exe, make minor changes to generated code
"wsdl.exe AXLAPI.wsdl axlsoap.xsd" which will result in AXLAPIService.cs.
Resulting class AXLAPIService in AXLAPIService.cs needs at least three changes:
a. Create an ICertificatePolicy-derived class which will later be associated with our service. This class is a brute-force approach to policy and certificate management. This is necessary in 5.x and 6.x AXL due to usage of HTTPS.
public class BruteForcePolicy : System.Net.ICertificatePolicy
{
public bool CheckValidationResult(System.Net.ServicePoint sp, System.Security.Cryptography.X509Certificates.X509Certificate cert,
System.Net.WebRequest request, int problem)
{
return true;
}
}b. Modify service constructor to take username/password credentials, CallManager IP as an argument, and associate the BruteForcePolicy class with the static CertificatePolicy manager.
public AXLAPIService(string ccmIp, string user, string password)
{
System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();this.Url = "https://" + ccmIp + ":8443/axl/";
this.Credentials = new System.Net.NetworkCredential(user, password);
}c. .NET uses the expects header differently (http://issues.apache.org/bugzilla/show_bug.cgi?id=31567). There are some workarounds to this problem as listed below:
i. Override the GetWebRequest method to use HTTP 1.0 due to error between TOMCAT/AXIS and .NET HTTP 1.1 Web Service request mechanism.
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
System.Net.HttpWebRequest request = base.GetWebRequest (uri) as System.Net.HttpWebRequest;
request.ProtocolVersion = System.Net.HttpVersion.Version10;return request;
}ii. Override the GetWebRequest method to manually embed authentication string. If you do this, do not use the line
this.Credentials = new System.Net.NetworkCredential(user, password);
from the constructor provided in point b of this section.protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
System.Net.HttpWebRequest request =(System.Net.HttpWebRequest)base.GetWebRequest(uri);
if (this.PreAuthenticate)
{
System.Net.NetworkCredential nc = this.Credentials.GetCredential(uri,"Basic");
if (nc != null)
{
byte[] credBuf = new System.Text.UTF8Encoding().GetBytes(nc.UserName + ":" + nc.Password);
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credBuf);
}
}
return request;
}iii. If using wsdl2wse (WSE library) instead of wsdl.exe, you can not override the HTTP version or supply HTTP headers manually. If one wants to use WSE, you have to set Keep-Alive header to false for the generated class, or set the user-agent to restricted. This technique will work in lieu of approach in point i and ii above.