how to sign saml 2.0 authnrequest in c# - c#

I am the Service provider using native c# code to generate saml 2.0 AuthnRequest and consuming the SamlResponse. The client has asked us to sign the saml AuthnRequest and then send it to them. We are sending it as http-POST.
Here's the data we have:
The metadata of idp containing their x509 certificate.
Our own x509 certificate along with our private key. Used this tool to get a self signed one https://www.samltool.com/self_signed_certs.php
Our own SP Metadata (entity descriptor) Signed using the self-signed certificate and private key, using this tool https://www.samltool.com/sp_metadata.php
Now, with the above information, how do i sign my AuthnRequest ?

Related

Issue Connecting to ADFS using SAML2 protocol (using Sustainsys.Saml2.Owin package)

I'm new to SAML 2.0 signing protocol.
Currently in my MVC application I'm using WS federation as signing protocol, now I have to use SAML 2.0 signing protocol.
Our IDP is ADFS and AUTH Plugin is Sustainsys.Saml2.Owin package
First I are trying to connect with SAML 2.0 signing protocol without self signed certificate.
For that in AFDS I have set Get-ADFSRelyingPartyTrust is already set to false
please refer below screenshot of ADFS
When trying to access the application after providing login info getting below error
Error details: MSIS7085: The server requires a signed SAML authentication request but no signature is present.
When I decrypted the SAML response with the help of fiddler, found incorrect saml2:Issuer value
after decrypting SAML request listed below
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="id95832a0e04ac48d7a3d33d7a185f4906" Version="2.0" IssueInstant="2023-02-08T08:47:26Z" Destination="https://dummy.com/adfs/ls/" AssertionConsumerServiceURL="https://dummy.dev/Saml2/Acs">
<saml2:Issuer>**http://dummy.com/adfs/services/trust**</saml2:Issuer>
</saml2p:AuthnRequest>
but the correct SAML request should have below listed saml2:Issuer value
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="id95832a0e04ac48d7a3d33d7a185f4906" Version="2.0" IssueInstant="2023-02-08T08:47:26Z" Destination="https://dummy.com/adfs/ls/" AssertionConsumerServiceURL="https://dummy.dev/Saml2/Acs">
<saml2:Issuer>**https://dummy.dev**</saml2:Issuer>
</saml2p:AuthnRequest>
Please help me how to define saml2:Issuer in application code side , so that in SAML request it works perfectly.
Please let me known if any other information is required.
Thanks in advance...
Need SAML 2.0 as signing protocol for connecting with IDP as ADFS by using Sustainsys.Saml2.Owin package

Signing JWT for ADFS to obtain access token

I am new to ADFS, OAuth and JWT and have been looking at this for a number of days; Sorry if silly question or already been answered.
I read this guide that deals with authenticating a client using a cert: signing a JWT with a certificate and verifying with the certificate manually uploaded to ADFS: https://learn.microsoft.com/en-gb/archive/blogs/cloudpfe/oauth-2-0-confidential-clients-and-active-directory-federation-services-on-windows-server-2016
It's kind of what I want but not quite - I would like to use certs for user authentication; I would like to sign the JWT with a certificate unique to AD user and be able to have ADFS verify the user in AD as according to the certificate - avoiding the need to manually upload a certificate (plus avoiding the need to upload countless number of user certificates!). Is this possible?
The other way of doing it, I was thinking of a JWKS URL with a ton of public certs but that seems mad! (Not sure how I go about producing this endpoint anyway).
I appreciate any guidance or pointing me to read articles...
Cheers!
This sounds like a feature request to have ADFS support your bespoke idea for signature creation on the ADFS side.
To help you understand this in context to how JWT is meant to work:
JWT signatures are either:
a shared-secret (defined by the JWT producer) for the HMAC-based JWT implementation.
JWK (served by JWKS) for the RSA/ECDSA implementation, or;
Or concisely:
HMAC-based; shared secret, no confidentiality, claims are public
RSA/ECDSA; private key generated by the JWT consumer so it can securely decipher (decrypt) claims data that was encrypted by the JWT producer using the public key corresponding to the client private key. Encryption makes claim data confidential. Signatures are therefore (as already described) using public keys (accessed by the client via JWKS URL hosted by the ADFS server) to do the verify method on each end without exposing the private key in more than the location it was intended to be used for decryption purposes.
It seems to me you're after a specific HMAC variation based on sharing a Certificate intended as a shared-secret, and that would undoubtedly require ADFS to sign using your shared-secret rather than generate a shared-secret on the server.
If you are after a Certificate based Authentication (authentic identity) I would strongly suggest you look at a Certificate authentication scheme rather than try make a modified-JWT scheme to fit your ideas, which it was not designed for. Mostly because you do not control the ADFS source code and can not make it perform non-standard methods or use untrusted (client provided) shared-secret for signature generation when the JWT specification does not support this.
(Also you're trying to do Certificate Authentication using JWT that is an Authorization scheme in this ADFS context)

JWT Authentication in Web API using System.IdentityModel.Tokens.Jwt

I am trying to implement JWT token based authentication in Web API using System.IdentityModel.Tokens.Jwt and Identity.
I am following this
Web.config
<appSettings>
<add key="issuer" value="http://localhost/" />
<add key="secret" value="IxrAjDoa2FqElO7IhrSrUJELhUckePEPVpaePlS_Xaw" />
</appSettings>
Though I was able to successfully able to implement and run the application with authentication, I am not sure what these settings are for. What ever I given in issuer, still the application works as expected. Can someone please provide some insights on issuer and secret?
I am using postman to test the token and the API
From the same site that you followed the tutorial (Create a RESTful API with authentication using Web API and Jwt) he says about the properties:
Issuer - a unique identifier for the entity that issued the token (not to be confused with Entity Framework’s entities)
Secret - a secret key used to secure the token and prevent tampering
But to try and explain this a little more precise:
The issuer is basically the server or site or whatever that issues the token to the client.
And the secret is something that the server (or whatever) knows about. The secret can be used to create a signature that can verify that messages hasn't been altered on the way. More on that on jwt.io JWT Secret :
To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.
Hope this helps!

Validate if certificate is revoked

I have the following situation:
Java Applet for digital signature - on client side
Validation of digital signature and digital certificate - on server side
I'm using the following C# code to validate the signature and the certificate:
ContentInfo content = new ContentInfo(pdf);
SignedCms signedMessage = new SignedCms(content, true);
signedMessage.Decode(assinatura);
signedMessage.CheckSignature(false);
Where:
pdf - signed pdf file
assinatura - pdf's signature - in my case, the signature it's not with the pdf file
By the tests I made, the code validate the certificate chain, the expiration and others...
However, I would like to know a few things:
This code validates that the certificate used for signing is revoked? If it does not validate, how could I make such a validation system at this point?
Is there a way to create a certificate that is revoked for testing?
Revocation check is performed by
Obtaining CRL that can contain information about the status of the certificate
Sending OCSP request to the server authorized to respond to such requests
If OCSP server's URL is present, OCSP is the preferred (for security) method to check revocation, but in general both checks should be performed.
OCSP and CRL operations are supported by our SecureBlackbox, CryptLib, BouncyCastle. In SecureBlackbox you will find a high-level CertificateValidator class which does all checks for you (at the same time letting you interfere in all aspects of the procedure).
There's no way to create a revoked certificate unless you run your own private certificate authority (but if you did, probably there would be no question). The reason is that you can't put your certificate's ID to the CRL sent by CA (or make the third-party OCSP responder do this).
Oh, I can see one way - buy a certificate, then contact the CA and tell them that you've disclosed the private key. They will block the certificate. But this is quite costly method :).

SmartCard security, how do you authenticate the certificate as not fake?

I'm trying to develop an ASP.net site that reads the clientCertificate to ensure a smart card was used to access the website (trying to do away with username/password login).
The process I have in my mind is:
User registers an account and C# records user's clientCertificate (public).
The user can then log in the next time with that same clientCertificate, and they are now an authenticated user if hash valid.
I will use the code below to ensure authenticity of certificate. The browser should deal with private keys and ensure the certificate was NOT faked.
Based on Subject+certificate combination, C# assigns them their role-access.
The following code can be used for authenticity of certificate right?
X509Certificate x509Cert = new X509Certificate(Request.ClientCertificate.Certificate);
SHA1 sha = new SHA1CryptoServiceProvider();
byte[] hashvalue = sha.ComputeHash(Request.ClientCertificate.Certificate);
byte[] x509Hash = x509Cert.GetCertHash();
// compare x509Hash WITH hashvalue to ensure they are a match.
// If not, possibly faked certificate, not a real smartcard???
Is this how SmartCard authentication process should work???
If you just need to authenticate users with client certificates you should do this in IIS. You do not need to add any code at all to your application:
Specify Whether to Use Client Certificates (IIS 7)
Unless you need to link client certificates with database accounts or perform an additional validation step. But still for client certificate authentication I would stick with IIS settings.
Update:
In case you need to manipulate the client certificate you can do:
X509Certificate2 x509Cert2 = new X509Certificate2(Page.Request.ClientCertificate.Certificate);
And then access its properties such as:
x509Cert2.Subject
However, leave the validation piece up to IIS. If the client presents a bad certificate your asp.net code will not even execute since IIS will reject it
See this thread, sir. You do not need to verify authenticity explicitly in your code. IIS will do it for you.
Does IIS do the SSL certificate check or do I have to verify it?
IIS even tries to check revocation lists (however, this is often disabled if the CRL is large). An OCSP responder should be used to validate in cases where the CRL is very large or latency in checking it is high http://www.axway.com/products-solutions/email-identity-security/identity-security/va-suite.
Client-certificate authentication is done during the SSL/TLS handshake.
It is usually done using a Public Key Infrastructure, whereby the server has a (fixed) list of trusted CA certificates which it uses to verify the client certificate (in the same way as clients to it for the server). Once the certificate is presented to your application after this stage, you will know that:
the client has the private key for that certificate (guaranteed by the Certificate Verify message in the TLS handhsake (the SSL/TLS stack will verify this for you, no need to implement anything);
the client has the identity described in the certificate, because you will have verified it against your trusted CA.
The verification against a trusted CA requires the user to be registered with that CA in advance. You can't just authenticate any certificate if it hasn't been issued by a CA you trust. (Mapping the certificate's subject to a local user ID is another matter: you could do this upon first connection if needed: have your own database or directory service to map the Subject DN to another kind of user ID in your application, for example.)
User registers an account and C# records user's clientCertificate
(public). The user can then log in the next time with that same
clientCertificate, and they are now an authenticated user if hash
valid.
It sounds like you want to allow any certificate to be presented and use it for the initial registration, without necessarily resorting to a commonly trusted CA.
This is possible in principle, and I've done this to explore alternatives to PKI in Java.
To do this, you need to let any certificate through as far as the SSL/TLS handshake is concerned, and verify the certificate itself later. (You do need to use some form of verification.) You are still guaranteed with this that the client has the private key for the public key certificate it has presented.
Doing this requires two steps:
You need to be able to advertise the fact that you're going to accept any certificate, by sending an empty list of certification authorities in the Certificate Request TLS message (explicitly allowed by TLS 1.1).
Configure the SSL/TLS stack to trust any certificate (once again, when you do this, do not forget to implement your own verification system within your application, otherwise anything will really get through).
In .Net, while it should be possible to address the second point using a remote certificate validation callback, I have never found a way to alter the first point (this was also asked in this question).
In Java, the JSSE's X509TrustManager allows you to address both points.

Categories

Resources