|
security
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Using a Java Keytool created certificate in HTTPWebRequest.ClientCertificatesa working version where I POST in a multi-part form including a file, etc, using HTTPWebRequest. Works fine via HTTP, however I now want to ge tit working over HTTPS. The instructions to enable HTTPS on this custom server require you to install a certificate created using the Java Keytool with the following parameters keytool -selfcert -genkey -keystore certs -alias myalias -dname "cn=www.somedomain.com,ou=SomeUnit,o=Some Pty.Ltd.,l=Melbourne,st=Victoria,c=AU" -keyalg "RSA" –validity 365 In the above example command line I have replaced the alias and dname with some other non-relevant text but apart from that it's all correct. The output is a file called "certs" which I then install into the HTTP engine. This all seems to work fine. However, I can't quite figure out how to get the "certs" keystore installed on my Vista client so that the following code can read it string certificateName = "SomeCertName"; X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly); X509Certificate2Collection certificates = store.Certificates.Find (X509FindType.FindBySubjectName, certificateName, true); X509Certificate certificate = certificates[0]; webRequest.ClientCertificates.Add(certificate); I have looked everywhere for some information on this, but the best I could come up with was installing the certificate using "Internet Options > Content > Certificates > Import..." but this requires the "certs" keystore file to be of a certain type when importing and I can't work out which. Am I going about this in the wrong way? Can anyone point me at a good resource for this kind of stuff ? At the very least does anyone know which type of Certificate the Java Keytool creates ? Any help very much appreciated Al Is your goal here to just get SSL working with the server or to also
authenticate the client with SSL client certificate auth? If you just want an HTTPS connection to the server, you don't need to specify anything with client certs on the client side. You just need to get the client to trust the server's certificate. There are two ways to do this: - Fix the chain such that the client trusts the server's certificate with default policy, or - Implement a custom policy that ignores some or all of the SSL policy errors that you don't want to fix To fix the chain locally, the Windows client must trust the server's certificate. For that, the issuer must chain up to a trusted root, the subject name must match the host name in the URL and the certificate must be in its validity period. If you don't want to fix the trust chain because you don't care about proving the identity of the server and just want encryption, then you can implement a callback that allows you to ignore SSL errors. If you really do want client cert auth, that is likely more complex. You'll have to deal with the above mentioned stuff, but then you'll also need to issue a valid client certificate to the client. You can't use the server's certificate on the client (unless you've created both a client and server authentication cert, but that would be a weird PKI usage). -- Joe Kaplan-MS MVP Directory Services Programming Co-author of "The .NET Developer's Guide to Directory Services Programming" http://www.directoryprogramming.net "bigAPE" <alex.madd***@gmail.com> wrote in message I am writing some code to connect to a custom Java HTTP server. I havenews:fd56c8f6-f821-4b7f-bf30-9f7fac73c3dc@g1g2000pra.googlegroups.com... a working version where I POST in a multi-part form including a file, etc, using HTTPWebRequest. Works fine via HTTP, however I now want to ge tit working over HTTPS. The instructions to enable HTTPS on this custom server require you to install a certificate created using the Java Keytool with the following parameters keytool -selfcert -genkey -keystore certs -alias myalias -dname "cn=www.somedomain.com,ou=SomeUnit,o=Some Pty.Ltd.,l=Melbourne,st=Victoria,c=AU" -keyalg "RSA" –validity 365 In the above example command line I have replaced the alias and dname with some other non-relevant text but apart from that it's all correct. The output is a file called "certs" which I then install into the HTTP engine. This all seems to work fine. However, I can't quite figure out how to get the "certs" keystore installed on my Vista client so that the following code can read it string certificateName = "SomeCertName"; X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly); X509Certificate2Collection certificates = store.Certificates.Find (X509FindType.FindBySubjectName, certificateName, true); X509Certificate certificate = certificates[0]; webRequest.ClientCertificates.Add(certificate); I have looked everywhere for some information on this, but the best I could come up with was installing the certificate using "Internet Options > Content > Certificates > Import..." but this requires the "certs" keystore file to be of a certain type when importing and I can't work out which. Am I going about this in the wrong way? Can anyone point me at a good resource for this kind of stuff ? At the very least does anyone know which type of Certificate the Java Keytool creates ? Any help very much appreciated Al Outstanding. Thanks for all your advice. I was about to post back
saying pretty exactly that. I now have the connection working but I did the following: (1) Created the server X509 DER certificate using OpenSSL with the CN set to the server name (the cause of my previous RemoteCertificateNameMismatch) (2) Installed and configured HTTPS on the Server using this X509 DER certificate (3) Connected to the server via HTTP using Internet Explorer (4) Installed the Certificate from the Server to the Personal store (5) Ran the test C# application which loaded up all the Certificates found in the Personal Store using X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly); foreach (X509Certificate cert in store.Certificates) { webRequest.ClientCertificates.Add(cert); } (6) Implemented the ServerCertificateValidationCallback as follows ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback (RemoteServerCertificateValidationCallback); ... public static bool RemoteServerCertificateValidationCallback (Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; // sorry, awful I know } (7) HTTPS calls now work at the expense of ignoring the RemoteCertificateChainErrors.ChainStatus = "Untrusted Root" error. Is this what have suggested. Do I not need to deal with steps 3 or 4 ? Al On Dec 4, 9:31 am, "Joe Kaplan" <joseph.e.kap***@removethis.accenture.com> wrote: Show quoteHide quote > Is your goal here to just get SSL working with the server or to also > authenticate the client with SSL client certificate auth? > > If you just want an HTTPS connection to the server, you don't need to > specify anything with client certs on the client side. You just need to get > the client to trust the server's certificate. There are two ways to do > this: > - Fix the chain such that the client trusts the server's certificate with > default policy, or > - Implement a custom policy that ignores some or all of the SSL policy > errors that you don't want to fix > > To fix the chain locally, the Windows client must trust the server's > certificate. For that, the issuer must chain up to a trusted root, the > subject name must match the host name in the URL and the certificate must be > in its validity period. > > If you don't want to fix the trust chain because you don't care about > proving the identity of the server and just want encryption, then you can > implement a callback that allows you to ignore SSL errors. > > If you really do want client cert auth, that is likely more complex. You'll > have to deal with the above mentioned stuff, but then you'll also need to > issue a valid client certificate to the client. You can't use the server's > certificate on the client (unless you've created both a client and server > authentication cert, but that would be a weird PKI usage). > > -- > Joe Kaplan-MS MVP Directory Services Programming > Co-author of "The .NET Developer's Guide to Directory Services Programming"http://www.directoryprogramming.net"bigAPE" <alex.madd***@gmail.com> wrote in message Hi Joe,
Sorry, just answered my own question. Setting the following just accepts the Server Certificate without having to adding any to HTTPWebRequest.ClientCertificates ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback (RemoteServerCertificateValidationCallback); public static bool RemoteServerCertificateValidationCallback (Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; } Is that what you were referring to when you talked about not needing the Certificate ? Al You only specify a client certficate if you need client certificate
authentication. If you just want SSL encryption of the channel, the client certificate is not needed. Essentially, the client will remain anonymous (at least at the SSL level) and the server will be identified by the certificate it presents. So, basically you tell me if you need client cert auth. :) From what you've said so far, it doesn't sound like it to me. As to whether you want to use the callback approach to avoid the chain verification issue or fix the chain, that is up to you and your requirements. In a closed network where there is no chance of an attacker trying to spoof the server, you may not care if the server is properly identified by its certificate and may only wish to ensure that an encrypted connection is negotiated. In a public-facing scenario, that would be a bad decision. You also wouldn't use a self-signed certificate for a "real" deployment in most cases either. They should only be for testing. Getting a certificate from a real CA is the better way to go. If you want to fix the chain so the client can verify without having to use the callback, you probably just need to ensure that the server's certificate is added to the local machine store trusted root certificates container on the client machine. That will make the server's certificate a root certificate and will allow it to chain. Then, as long as there is no name mismatch or validity period issue, the cert should be accepted with no error. Up to you how to proceed. :) -- Show quoteHide quoteJoe Kaplan-MS MVP Directory Services Programming Co-author of "The .NET Developer's Guide to Directory Services Programming" http://www.directoryprogramming.net "bigAPE" <alex.madd***@gmail.com> wrote in message news:1341d466-ace7-429d-804d-d19d0f21a16d@w1g2000prk.googlegroups.com... > Hi Joe, > > Sorry, just answered my own question. > > Setting the following just accepts the Server Certificate without > having to adding any to HTTPWebRequest.ClientCertificates > > ServicePointManager.ServerCertificateValidationCallback = new > RemoteCertificateValidationCallback > (RemoteServerCertificateValidationCallback); > > public static bool RemoteServerCertificateValidationCallback > (Object sender, X509Certificate certificate, X509Chain chain, > SslPolicyErrors sslPolicyErrors) > { > return true; > } > > Is that what you were referring to when you talked about not needing > the Certificate ? > > Al OK, I have managed to get a little further. I decided to go an
alternate route and use OpenSSL to create the certificate according to another set of instructions with the custom HTTP server. The result is a DER encoded X509 certificate which the server is now using on the HTTPS port. I know this because if I view the servers HTML page using HTTPS Firefox and IE throw a fit because the Certificate is not recognised. I can then Import the Certificate into my personal store. When running the C# code for the HTTPWebRequest if I cycle through the certificates using the following it is there and can be added as follows X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly); foreach (X509Certificate cert in store.Certificates) { webRequest.ClientCertificates.Add(cert); // this finds the certificate (validated by examining the certs in here in Debug) } Stream requestStream = webRequest.GetRequestStream(); <--- EXCEPTION THROWN HERE requestStream.Write(reqBytes, 0, reqBytes.Length); I get the following Exception when attempting to GetRequestStream() [System.Net.WebExceptionStatus.TrustFailure' "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel." "The remote certificate is invalid according to the validation procedure" So my question is... I have the certificate in my Personal store, I can see it in C#. IE can connect to the site happily now that I have installed the cert. So WHY am I getting this failure in the Trust Relationship ? Any thoughts Al
create exchange public folder contact
Don't understand System.Security.SecurityException Re: Code Access Security issue check a certificate in CRL Computing a hash with the managed SHA providers IPsec in Vista brastk virus doesn't allow to visit legitimate web sites 256 k encryption VIRUSES DES decryption bigger than expected |
|||||||||||||||||||||||