Binary Security Token from p12 vs Binary Security Token from jks - c#

I need to obtain the BinarySecurityToken to authenticate to Soap WebApi, I know that BinarySecurityToken is certificate content encoded in Base64. When I test api in SoapUI the Binary sec token is generated from jks file from my certificate, everything works. The problem is when I need to connect to api form C# then I am using p12 cert and getting encoded base64 content of cert like in jks file but the values are different and BinarySecurityToken from p12 is not working with Soap api.
Conclusion: BinarySecToken generated from jks is different than generated from p12.
Is there any way to generate BinarySecToken as same as from jks file?
Is any way to work with jks files in c# ?
This is how I get the BinarySecToken:
X509Certificate2 cert = new X509Certificate2(certPath,"pass");
var content = cert.RawData;
var base64content = Convert.ToBase64String(content);

BinarySecurityToken in .jks file is raw content data but with one difference. Token in jks file contains file size at the begining, token data generated from .p12 is the same data as jks but without file size. In my solution I solve it in other way. I think there is no solutions when you need to obtain BinarySecurityToken from file as raw data. There are other api mechanism that will solve it for you. When you want to obtain token as raw data from file, you do it something wrong and for sure that won't solve your issue.

Related

soapui binarysecuritytoken not matching the one generated in C#

We are trying to connect to an external api from our organisation via soap. When we do the connection via soap ui with the wsse security as binarysecuritytoken(using pfx certificate) it works fine and yields the expected output. Since we are going to call the API programmatically we are doing the same in C#(beginner level expertise) but the binarysecurity token we generate by exporting the pfx certificate doesnt match with the one generated by soapui. We are using the below code to generate the token..
When we try the below option the error is - ASN1 parse of PKIPath Failed
Option 1
var c= new X509Certificate2(PFXFilePath, CertificatePassword);
var export = c.Export(X509ContentType.Cert, CertificatePassword);
var base64 = Convert.ToBase64String(export);
Option 2
var c= new X509Certificate2(PFXFilePath, CertificatePassword).GetPublicKey();
var base64 = Convert.ToBase64String(c);
TOken generated by Option 2 is a subset of the token generated by SOAP UI
I have dugged around a lot into SO archives and couldnt find the correct solution for this. Please help

How to properly export a cert file using c#?

I have an API that creates and exports certificates, I also have access to the UI to export them manually. The problem here is: when I export a cert using c# the API returns a well-formed base64 string, if I take this string and convert it to an X.509 object it still works, but, when I export this to a cert file it seems to be insecure. If I export the certificate manually it returns the exact base64 string, but it seems to be secure and well-formed.
So, what's the difference? or how could I export the base64 string to a cert file while avoiding insecurity issues?
Thanks in advance.
My current approach is:
File.WriteAllBytes("certification.cer", GetCertificate(base64).Export(System.Security.Cryptography.X509Certificates.X509ContentType.Cert));
And:
File.WriteAllBytes("certification.cer", Convert.FromBase64String(base64))

Create SAML SLO request

As a service provider (SP), i'm trying to create request for SLO using the URL redirect flow. After going through a lot of articles, this is what i came up with:
Create a logout request xml and digitally sign it
Convert the request xml to base64 url encoded string
Append the base64 encoded request xml to the SLO url as a querystring
Redirect page to the above constructed url (IDP)
IDP will then perform necessary SLO steps for all SPs at its end and
redirect back to our current application (which initiated the SLO
request)
Parse above response and show message in UI accordingly
However, when i got into the actual implementation, i'm faced with the following challenges, some of them not specific to SAML SLO.
To digitally sign the logout request xml, is it mandatory to
load/import the x509 certificate from .pfx file or can i use any
certificate from the certificate store which has private key?
For demo purpose, I've successfully signed the request using a certificate in my local system which has private key. This process appends the signature and pulic key information in the logout request xml.
I've encoded (Base64Url) the request xml but the resulting string length is too long (more than 4k chars), which would exceed the maximum length allowed in URL/GET request. Have i got this step wrong?
None of the articles/SAML spec mentions how the querystring should look like. Is the querystring parameter name defined by the SAML spec (which i could have missed) or is it dependent on the IDP?
All in all, i feel that SAML spec lacks articles with proper implementation which is making it extremely difficult to get the hang of it.
Note: I didn't include any of the codes i've written so far since my questions can be answered without them. However, if required, i can include them.
Few of the many referenced articles:
SSO, SAML and SLO
SAML Logout Request (SP -> IdP)
Sign XmlDocument with X509Certificate2 and Verify in C#
I would strongly suggest using an existing SAML library instead of rolling your own.
Some of these are free and you can examine the source code to see how to do it.
Or alternatively just use the stack itself!

How to add JKS file to HttpClient request

I'm trying to send http requests with a cert,
when in using the SoapUi I'm adding a JKS file to the request and it works great, and now I'm trying to implement this in .Net Core code.
I'm using HttpClient for the request and I don't know how can I attach the JKS file.
Any Ideas?
Thanks
JKS is a Java proprietary format for key stores, used by default until Java8. Since Java9 the default format is PCKS#12.
C# can not read this kind of files, but it is easy to convert from JKS to PKCS#12 using keytool or KeystoreExplore
keytool -importkeystore -srckeystore <jks_file_name.jks> -destkeystore <pk12_file_name.p12> -srcstoretype JKS -deststoretype PKCS12 -deststorepass <password>
See this answer to invoke a http service using client certificates https://stackoverflow.com/a/10170573/6371459

How to generate BinarySecurityToken (X509PKIPathv1) from .p12 file

I am trying to consume a Java web service from a C# client. The service requires BinarySecurityToken element with value type X509PKIPathv1.
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1">
MIIH......
</wsse:BinarySecurityToken>
Since WCF does not support X509PKIPathv1 value type, I am generating the SOAP message by hand, signing it using the SignedXml class, encrypting it using the EncryptedXml and sending it using the WebClient class. As for the value of BinarySecurityToken element, I used the value generated in SoapUI for the same certificate, and it works.
But, I would like to be able to generate this value programmatically from .p12 file, and not having to paste it from SoapUI again every time when the certificate expires.
The WS-Security documentation is a bit vague, so I am not sure how to go about it. This is all the information it gives about this token type:
#X509PKIPathv1: An ordered list of X.509 certificates packaged in a PKIPath
How to generate this value from .p12 file in C#? SoapUI does it somehow.
So this may not be a fully solution to your problem but it may help you out somewhat.
This:
#X509PKIPathv1: An ordered list of X.509 certificates packaged in a PKIPath
means is a asn1 sequence or chain of certificates that you have used to sign your message. You can even see it here.
To give some context asn1 is way of representing data in way independent of the machine you are using. This data is binary and not human readable so you transform it to bade 64 and that is what you see in that field.
I am not entirely sure what the exact content of your .p12 file is but at the very least I assume it has the certificate of the private key you used to sign your message and maybe the chain until the publicly trusted certificate or CA.
I am mostly a C++ developer and I know openssl provides a C like api to read a certificate manipulate the underlying asn1 structure and the output it as a string.
Sorry for not providing with a greater level of detail or a code example

Categories