Use for every Reyling Party seperate client Certificate? - c#

I'm reading up on SSO and I used this tutorial http://chris.59north.com/post/2013/04/09/Building-a-simple-custom-STS-using-VS2012-ASPNET-MVC.aspx for creating a custom STS.
If I understood correct on the STS machine is installed a certificate. The reyling party sends the thumbprint of the x509 signature. So the relying party will accept only claims of a STS with the proper certificate. Is this correct?
If so, I would like to implement that every relying party is sending a certificate to the STS which the STS got installed too. On a request the STS look up in his trusted relying party list if the sent certificate is known by the STS.
Is this implemention a good idea and is this good practice? Is there a good ressource to implement this?
thanks

implementing a custom STS is hard work. I would advise you to have a look at windows azure ACS or the Thinktecture free STS as a starting point.
This being said, having a separate certificate for a relying party is a common practice. However, the private key of this certificate is normally stored inside some database in the STS (ACS and Thinktecture both support this). The relying party only knows the public key.
The security token (SAML2 or JWT) is then signed by the acs with the security token and the relying party can use the public key (or a thumbprint) to verify the signature.
Please also notice that a SAML2 token can also be encrypted (next to being signed) and that you can use a different certificate for that.
I personally would recommend using a seperate certificate it the STS (or your organisation) has some kind of website were "anybody" can register their application as a relying party. If all your elying parties are "internal" applications I would at least consider using a single certificate to sign all security tokens. This has the advantage that you can publish the (public) key in your Federation meta data document (located at FederationMetadata/2007-06/FederationMetadata.xml). If you wish to update the key, you can update it there (by first publishing new and old key there and later only the new key). Relying parties can then update there keys based on this meta data (adfs uses a similar approach).
So bottom line : having a seperate certificate per RP is good but having a single one (for signing - not encryption) is much easier to update.

Related

Self-signed TLS certificates in Intranet

I'm writing a system in C#, which consists of REST API server, written with HttpListener and WPF client app, with HttpClient and I want to use HTTPS.
As far as I know, on the server side all I have to do is run HttpListener with prefix with https and bind my certificate (creted for example with makecert) to proper port - now all communication is encrypted.
On the client side, I have to put the public part of certificate in Current User store, so that it can be trusted.
The server is not public, each client has his own instance accesible only after logging in to their VPN.
My questions:
1. Are self-signed certificates secure enough? Is generating new certificate for new client more secure(for example, from license data)?
2. How do I generate the "public part" and "private part" of certificate? How do I ship it?
It isn't a bank, so I don't want to overkill security, but I don't want to go "trust all certificates" way.
Security in general hinges on how well protected your private key is. The algorithm used can be the same as on a public signed certificate.
There is no inherit security gain or loss in using a self signed certificate.
The bigger problem is the distribution of your public key among the member systems. If you run a domain wide CA on your domain controller, it should be relatively easy.
If you do not, you might be able to do it via Group Policy.
In any case it requires admin intervention to get it to run on all your systems and again should the private key be compromised.
The problem arises should you have external clients not connected to your DC. Then LetsEncrypt is definitely the better choice.
I believe that you'll have to add the public key of the self signed certificate to the Trusted Root Certification Authorities store as well.
That is offcourse cumbersome since you'll have to do this on every client ...
Can't you use certificates issued by LetsEncrypt ?

I have several questions about the SslStream Class and about certificates

I have looked at about 10-15 different pages about the SSlStream class and about certificates and I haven't found one that completely explains everything to me. So I have a bunch of questions.
I am currently working on some SslStream code and I have a question about certificates. From my research it appears that the server requires a certificate if we are using TSL12. And it appears optional that the client needs a certificate.
1) Now if we design a system that the client needs a certificate do we use the same certificate for the client and the server? Or do they both use different ones?
2) Also looking at the Microsoft SslStream help page:
https://msdn.microsoft.com/en-us/library/system.net.security.sslstream(v=vs.110).aspx
How does the code know if those are the expected certificates?
3) In the Property page on a project under Signing you can Create a Test Certificate. When you click that button it asks for a Password. If a password is used how would that affect the SslStream code? The code on the Microsoft help page above doesn't deal with that at all?
4) Once I have a certificate for the server and the client can I just place them in a directory or do I need to put them in the store?
Thanks.
You can find most answers to your questions here
These are the different certificates. Client certificate used to check client identity. Server certificate used to encrypt key materials and to authenticate itself.
What means expected? You mean whether the client certificate is correct? You can write your own login to check client and certificate. By default expiration date is checked, where it's revoked or not etc. Read there to clarify.
It will create certificate and to use private key you will need to provide password to get it from storage
The base usage is to put it into the store. But you can also get it from .pfx file. You can read there about geting the key from file
1) Now if we design a system that the client needs a certificate do we use the same certificate for the client and the server? Or do they both use different ones?
The best practice is "one certificate per purpose". Think of a server authentication certificate as the "Warner Bros. Studios" sign hanging on the building as you pull up to the guard shack, and a client authentication certificate as an employee ID badge. They both inform the other party what's going on, but it feels a little out of place to then walk down the street to Universal and show your big Warner Bros. sign as identification.
2) Also looking at the Microsoft SslStream help page: https://msdn.microsoft.com/en-us/library/system.net.security.sslstream(v=vs.110).aspx How does the code know if those are the expected certificates?
The server authentication certificate you provide is correct, because you provided it.
If you give only one client auth cert, that's correct, because you provided it.
If you give multiple client auth certs then it will use an acceptable CAs list provided by the server TLS handshake to reduce the list, then it takes the first one that was acceptable.
3) In the Property page on a project under Signing you can Create a Test Certificate. When you click that button it asks for a Password. If a password is used how would that affect the SslStream code? The code on the Microsoft help page above doesn't deal with that at all?
Certificates don't have passwords, but PFX/PKCS#12 files do. You need that password to load the file into an X509Certificate2 instance (e.g. new X509Certificate2("servercert.pfx", "1Potato2Potato3Potato4")). Since SslStream won't do the loading for you, it doesn't talk about passwords.
4) Once I have a certificate for the server and the client can I just place them in a directory or do I need to put them in the store?
They should work fine when loaded from a PFX (you need the private key, so it can't be just a .cer). If the certificates can be one-time loaded into cert stores you can avoid the problem of loading or hard-coding PFX passwords... but that just depends on your deployment needs.

How to verify a rollover certificate?

I want to verify a certificate that comes from a SAML assertion (issued by AZURE AD)
They can rollover the public key at any time. I am assuming it means that I cannot manage them manually in the trusted root store.
I am using X509Certificate2.Verify() which is returning False if the certificate is not in the Trusted root store. Should I use X509Certificate2.Build() and set it to ignore if it is trusted?
SAML2 uses certificates as a convenient way of representing encryption/signing keys with a standard file format. The contents of the certificate are not relevant because the certificates should be directly exchanged between the involved parties. So there is no need to verify the certificate's validity, in many deployments it won't even validate.
With an Idp that regularly does key rollover you should load and trust the metadata of the Idp instead of directly configuring the certificate.
If you are implementing all of this on your own I'd recommend that you spend some time looking for an existing implementation. Making a complete SAML2 implementation that supports loading metadata is non-trivial and takes a lot of time.

WCF Single Authentication Multiple Endpoints

When creating a WCF service application I've implemented UserNamePassValidator for custom authentication and this works as expected.
But due to the large amount of functionality on the service, I've decoupled this into different service contracts such as a stock management service, location management service, task management service etc. and I've then exposed these on different endpoints within the same service.
This seems to work fine, however what I would prefer is to authenticate with one endpoint and have this session state maintained across all of the endpoints. At present what happens is I authenticate to one, I can then access the functionality of that service contract but if I was to connect to another endpoint it requires me to authenticate again.
My current crutch solution is to pass the ClientCredentials between forms on the client side for authenticating, and although it's using Message security so they're encrypted over the wire this is obviously not an ideal solution.
Is there a solution to first part? And if not, what's the best practice for storing user entered credentials in memory (during runtime) at the client side.
You can implement a scheme similar to WS-Federation. It is kind of Federated Security for service level.
Firstly, your Authentication endpoint should be called STS (Security
Token Service). What it does is authentication and return a security
token to the client.
Secondly, STS should be trusted by all the Service Endpoints. When
invoking the endpoints you should pass in the security token that STS
provided so that the endpoints will be able to read that token and
recognize that the token was issued by a trusted STS.
I have implemented one with Thinktecture at https://github.com/khoanguyen/Test-WS-Federation but sorry that I didn't give explanation you will need to research a little bit about WS-Federation and Thinktecture and WIF. But you should know that it is possible to do.
A lightweight solution that I am using for REST services for mobile project is below:
I set up a Authentication endpoint. That endpoint hold a DSA private/public key pair. When client is authenticated, this endpoint generate a token and sign it with DSA private key. Then I combine the signature and token together and return it as a security token to the client.
At the service endpoints, I gave them the DSA public key (from the key pair of Authentication endpoint). The DSA public key is for verifying the security tokens.
When client call the service endpoints, it attaches the security token as a Header of HTTP message. Then, the service endpoints read the header to retrieve the security token -> extract the token and the signature from the security token -> use DSA public to verify it.
The strategy for generating the token depends on your need. In my case, my token contains client's username, expiration timestamp. By using DSA, the hacker can extract all the token's data but they cannot alter it because they must have the DSA private key to sign the altered token. Our job is just keeping the private key in secret and don't leave any sensitive info (e.g password) in the token.
This is very cheap way. I don't need to access DB to verify user, just ensure got a valid security token, token's data is just for extra need, you can even generate a random token and sign it. No session state needed.

Other ways to encrypt WCF Connections

I'm currently working on a project that requires encrypted data be passed between WCF hosts. As I understand it there are only 2 ways to ensure that data passed over WCF is secure.
Using Certificates
Using a Domain (or having the same username and password on every machine on the network)
Using certificates can be expensive and complicated to manage and since we're not guaranteed to have a server class machine at every deployment a Domain is also out of the question. Having every machine use the same username and password is also problematic if that password ever needs to be changed.
Currently we use OpenSSH to tunnel our connections between hosts. Is there another option built into the framework that I'm unaware of?
Encryption requires a key. Keys are usually implemented as certificates. If you own both sides of the communication, you can create your own certificate for free without having to go buy one from a trusted root authority.
Here is an alternative. Works without IIS and SSL/X509 certificates.
If you are using a http endpoint, you can use a secure transport such as https.
Use traditional encryption of the data that you are placing inside the WCF container. Maybe something like the following:
http://www.obviex.com/samples/EncryptionWithSalt.aspx
The cheapest method is probably to run your own certification authority. This means you have total control over the certificates, but you do not have to pay for external certification. If you automate this appropriately, you can give every machine on your net a cryptographic identity and use your local certification to tie everything together.

Categories

Resources