Client certificate with IIS 7 - iis-7

I have a client who wants to secure the connection to his application with a client certificate. He doesn't want to map the certificate to a login.
He doesn't want to buy a certificate from trusted CA and wants me to provide him my own self-signed certificate.
I followed the steps from this article :
http://asoftwaredeveloper.wordpress.com/2011/12/30/x-509-certificate/
(every time I search on Google I end on this)
I managed to generate the two certificates and to set them both up in the client and server.
However, I still get the same 403.7 error.
Does anybody have a real step by step guide with ALL the steps?
Am I the only one who wants to do such a simple thing?
Why isn't it clearly described in the documentation?

Here is a step by step:
Generate your CA
Generate your client certs and add sign them with the CA
Open MMC (Windows 7 just type MMC in the dialog)
Click file>add/remove snap-in...
Click certificates then add
When prompted select computer account
When prompted again select local computer
Double click on certificates
Click on Trusted Root Certification Authorities
Click on certificates
Click on more actions > import
Find and select your Root CA Certificate
13 Open Internet Information Services Manager
Click on your server
Click on Server Certificates
Import your CA certificate
Click on your site
Click on bindings
Add a new one for https
Make sure to select your CA certificate
Click ok.
Return to your site menu
Click on SSL Settings
Check require SSL
Click on require in the radio buttons
Return to site's menu
Click on authentication
Enable anonymous authentication (it will still ask for a certificate)
Restart IIS (all of it, not just the site)
Install the client certificate into the browser
Go to the site with https:// and not http://
Browser should prompt depending on settings
Every client must trust the CA so you will have to convince every user to install your CA cert to their computer.

Related

Where does one place the Always Encrypted Certificate on an IIS 7.5 web server?

We have a SQL Server 2016 database that employs Always Encrypted. Our recently published ASP.net web site attempts to pull data from this database, and when it does we get this error:
Error: Failed to decrypt column 'EnSSd'. Failed to decrypt a column encryption key using key store provider: 'MSSQL_CERTIFICATE_STORE'. The last 10 bytes of the encrypted column encryption key are: 'B8-48-B3-62-90-0B-1D-A6-7D-80'. Certificate with thumbprint '97B0D3A64CADBE86FE23559AEE2783317655FD0F' not found in certificate store 'My' in certificate location 'CurrentUser'. Verify the certificate path in the column master key definition in the database is correct, and the certificate has been imported correctly into the certificate location/store. Parameter name: masterKeyPath
Now we know that this means that the certificate has not been placed in the proper location on the server. During development we simply placed the certificate in the Certificates snap-in under the Personal Certificate Store, and that worked, however now that the site has been published we tried doing the same on the web server but it's not working (we kind of figured it wouldn't).
Anonymous Authentication is enabled on the site and the anonymous user identity is IUSR. ASP.NET impersonation is disabled.
Where is the proper place to put the certificate?
UPDATE - we got it to work by changing the Application Pool Identity account to the one that created the Certificate. It was also the account used when adding the certificate to the Current User-Personal list on the web server. We would rather not use this account, so again, where is the proper place to put the certificate?
Always Encrypted requires that the user that is accessing the database to have both the public and private key, which is what it appears to require you to use the account to generate the certificate as they will have this key.
What I usually do is generate the certificate and export the cert with a private key and secure passphrase. Then import the cert with key into the personal store of the account you use to run the app pool. This cannot be a generic integrated account and must be a service account you specify.
run a powershell script as the user:
whoami
COMPUTER\myIISPoolUser
Set-Location -Path cert:\localMachine\my
Import-PfxCertificate –FilePath c:\AlwaysEncrypt.pfx
or use mmc.
whoami
COMPUTER\myIISPoolUser
certmgr.msc
You must also allow the APP Pool user load user profile
IIS can't recognize the certificate from local user, while creating the certificate in SQL server, by default it's putting in to the local user store, do the following things and make sure the certificate generated under local machine -> current user certificate store
Generate the encrypted columns with default certificates
Undo all encrypted columns in to plain text
Go to the certificate and key from the table security "Your DB - > Tables - > Security -> Always Encrypted Keys" and right click the "CEK_Auto 1" -> Script Column Encryption Key as -> Create to new window, keep this generated script
Delete the CEK_Auto 1
Do the step 3 for "CMK_Auto 1" certificate and delete this as well
in the "CMK_Auto 1" script change the certificate path "CurrentUser" in to "LocalMachine"
you example path will be like this "N'LocalMachine/my/G4452V8ERH035D2557N235B29MWR0SV834263G26'"
execute the CMK_Auto 1 and CEK_Auto 1 script
make sure the certificate generated local machine personal directory
it will work, if not test with IIS express that means still your certificate held in local user personal directory
rest all same make sure the "Column Encryption Setting = Enabled" added in the connection string.
Thanks
John Rajesh J
Running on IIS Express is different from running on IIS.
when we create Column Master Key (CMK) from SSMS at that time it generates Always Encrypted Certificate based on which location we have set while creating CEK.
For IIS, you have to generate certificate under MyLocalMachine, and then install certificate on hosting server with administrator rights. this will work for you.
You also need to give access of that certificate to IIS User. This can be done by right click on certificate and then click on manage primary key and add IUSR.
I had the same issue and here's what solved it for me.
Run SSMS as administrator
Right-click the first column you want to encrypt and select Encrypt column...
In the wizard to encrypt the column, under Select a master key source, select Local Machine and not Current User. (In my case, the Local Machine option only appears when I am running SSMS as administrator, hence #1).
Then launch mmc.exe. Under File > Add/Remove Snap in..., add the Certificates snap-in. When prompted, select Computer Account then Local Computer.
Now that Certificates has been added, expand Certificates (Local Computer) > Personal > Certificates, select the Always Encrypted Certificate you just created, right-click it and go to All Tasks > Manage Private Keys..., then make sure the user who is going to access the database has read permissions.
If you want to move the database to another machine, in this same MMC window, right-click the certificate, then All Tasks > Export. When prompted, choose the option to export the private key with the certificate (won't work if you don't). You'll need to enter a password before exporting. Once exported, import it to the other machine using that same MMC window. You'll need to enter the password you created when exporting and again make sure your user has read permission to it.

PAW: Remembering trusted self-signed certifiicates

I am developing an API using a local server with a self signed SSL certificate.
Every time I make a request with PAW I get a dialog warning me that the certificate is self signed, and asking me if I would like to proceed.
This gets tiresome after the first few hundred requests.
Is there a way to tell PAW that I trust this certificate?
Here are the steps:
When the alert "Paw can't verify the identify of the remote server..." is shown
Click "Show Certificate"
Check the box "Always trust ... when connecting to ..."
Hit "Continue"
You probably will have to enter your system password to allow the Keychain to mark this certificate as trusted
Then on next calls, it won't prompt you again. See the short screencast here: http://cl.ly/3r102z170X3F
An alternative (but unsafe) way is to uncheck "Validate SSL Certificates" in the Preferences (Paw menu > Preferences), under the "HTTP" tab.
Hope this helps!

Using HTTPS with IIS and ASP.NET

I'm using ASP.NET, and IIS web server. I want to use HTTPS protocol on my web site. In my IIS web server, I binded my web site on port 443 using following procedure:
Open IIS
Chose site I want to configure (in my case "My Test site")
Click Bindings on right side of window
In new window I deleted http, and added https (IIS asks you a
certificate file, which I previously created)
Click OK
Click browse on right side of IIS window
Am I using HTTPS now, and is all my data is encrypted?
It should be. However to ensure that the data is encrypted, you can do this further check.
Open the site in the browser and if you are using firefox, you should see a green colored label near the address bar, on internet explorer, you will see a lock sign - in short, there will be some sort of security information. Open it and check it. It will show the status of certificate and will also show you if the site is protected or not.
This is the final test at client side. If you have proper certificate installed which could be validated, it would say that the site is protected, otherwise it would say that the data is encrypted but the certificate is not valid - kind of security exception.

Accessing Smartcards from a Web Site

A number of Countries have implemented electronic id cards, that their citizens can use to securely access online facilities like banking.
I am interested in learning how to support these cards, but tracking down documentation on how to do this from an IIS hosted website is a real PITA: In MSDN for example the bulk of the smartcard documentation covers the end to end scenario of linking smart cards to domain logins in a corporate environment.
I am just trying to authenticate the holder of - for example, a Spanish DNI-e card and perform an OSCP validation of the card via http://ocsp.dnie.es/
Now, its seems that, rather than explicitly detecting the smart card insertion, I need to create a login page on the server with SSL client authentication forced - but how do I configure one request to require ssl client authentication and to pick the correct client certificate?
Indeed, configure your server to require client certificate authentication. You will receive the client authenticator details in the headers.
You can force to only accept specific certificates by configuring the public root certificate of those client certificates on the server and removing all others that you are not interested in. In the authentication request going from your server to the browser, only the root certificates are listed that are trusted on your server system. The client browser will only offer client certificates that are somehow related to that root.
In an Microsoft environment you would configure your IIS to require SSL on your login page. Additionally, require SSL client authentication using a certificate.

WCF, Certificate Authentication - Common Errors and Confusing Arguments

I am trying to setup a WCF service to use a Certificate for Authenticating the client. I have read tons of posts on how to create the certificate, and I have been able to do so (finally).
I am installing the Cert Authority and the Cert on a server that runs Windows 2008 R2. When I open the MMC Certificates Snap-in, I choose Computer Account. Is this correct? I am doing this because my WCF service will run in a Windows Service, and will be running even when no user's are logged in. But admittedly, I don't know what the difference is between the three options:
My user account
Service account
Computer account
Once the snap-in loads, I import the Authority Cert into Trusted Root Certification Authorities. Then, I import the cert into Trusted Publishers. I don't encounter any errors when doing this. When I do the import, of both the Authority Cert and the Cert signed by that authority, I don't make any reference to the .pvk file. It is my understanding that the private key is embedded in either the cert or the authority cert. Here are the commands I use to create each cert:
MakeCert.exe
-n “CN=InternalCA”
-r
-sv InternalCA.pvk InternalCA.cer
-cy authority
MakeCert.exe
-sk InternalWebService
-iv InternalCA.pvk
-n “CN=InternalWebService”
-ic InternalCA.cer InternalWebService.cer
-sr localmachine
-ss root
-sky exchange
-pe
Notice I used -ss root. I have seen many posts using -ss My. I don't really understand what the difference is or when it is appropriate to use each value.
My WCF service runs on this machine inside a Managed Service (Windows Service). When I start my windows service, which hosts the WCF service, it crashes immediately and a seemingly common error is reported in the event viewer:
System.ArgumentException: It is likely
that certificate 'CN=TempCertName' may
not have a private key that is capable
of key exchange or the process may not
have access rights for the private key
I have found posts that say I need to grant permissions to the user running the service to the key.
This one seems to be a popular answer here on stackoverflow: Grant access with All Tasks/Manage Private Keys
But I don't have the option of All Tasks/Manage Private Keys
But I'm not clear on how to do that. But also, the service is running under my domain account, which is an administrator and is also the same user that installed the cert.
Please Help :)
Here's the best link that should help you get your self-hosted SSL WCF service to work with your own custom CA/certificates: SSL with Self-hosted WCF Service.
After you get it working from the guide above, you may want setup your service programatically to use the right certificate during installation-time.
I find that verifying my HTTP.SYS configuration with the HTTPCfgUI tool to be easier than via the command line httpcfg/netsh commands.
Next, if you still encounter errors, you can debug further using WCF Tracing. Additionally, you should turn on WCF Message Tracing as well. You can trace the .NET network stack too, if the WCF tracing doesn't provide enough information.
You can test if your certificate/CA pair on the service is working by hitting your service URL in a browser on another machine. It should first state that the certificate is invalid. Then, import the CA on the machine into the trusted root, and hit the service URL again. This time it should display the service description page as usual, with no warnings.
I think you are close. Here are some suggestions:
Make sure you are getting a private key attached to your certificate in the second step. You have to run the command in an elevated process -- even if you have Admin privileges, you have to, for example, right-click and "Run as Administrator" to start the command shell you use for this command. Otherwise, you won't get the private key into the localMachine store.
I would use -ss my and put the certificate (with private key) into the Personal store. Here I see this:
cc.ClientCredentials.ClientCertificate.SetCertificate(
StoreLocation.CurrentUser,
StoreName.My,
X509FindType.FindBySubjectName,
"contoso.com");
and so wherever you are pointing to in your equivalent, put the certificate there.
You don't need to import the private key of the CA cert (the first one you created). That's only kept around to sign more certificates with MakeCert. You will need a copy of that CA certificate (without the private key!) on the client that is connecting in, otherwise the client won't be able to validate the InternalWebService certificate.
You don't really need the CA certificate locally on the server machine, because it will only be needed by the client. But it doesn't hurt, and would be needed if anything on the server connects to the service locally. Also, it makes the InternalWebService certificate look good on the MMC snap-in. You can try with and without the CA in the Trusted Root store and you'll see what I mean. But in any case, I would not put the private key of the CA into the local computer store.
Check the private key permissions for InternalWebService from the MMC snap-in (right-click on the certificate, then Tasks, Manage Private Keys...) If you import under a different user account than the service runs under, then certainly it won't have access yet, and you have to go give it access. Otherwise the service will get the certificate, but it will appear that the certificate does not have a private key.
To summarize:
Run with Admin privileges to make sure the private key of InternalWebService is really getting into the certificate store. (You'll see a little key on the certificate in the MMC snap-in, and right-clicking on the certificate will have an option "Manage Private Keys..." which is not present if there is no private key attached.)
Put the InternalWebService in the place where you Web service is looking for it. I would guess "Personal" (a.k.a. "my") but you know where that is in your service config. Whether current user or local machine, look in your config.
Give access to the InternalWebService certificate private key.
Put the CA certificate -- without its private key -- under Trusted Root, and you'll need to put that on the client as well (or otherwise have the client accept an "untrusted certificate" at its end.)

Resources