I am working on OIOSAML with ADFS 2.0. I need the IdP response to be signed as well as encrypted. Below is my understanding on how signing and encryption of SAML request and response works:
SP signs the request using its own certificate key (Key-1)
IdP verifies the request using SP's public key (Key-1)
IdP signs the response using its own certificate key (Key-2)
IdP encrypts the response assertion using certificate key provided by SP (Key-3)
SP verifies response using IdP's public key (Key-2)
SP decrypts the response assertion using its own private key (Key-3)
If I keep Key-1 and Key-3 same, everything works. As my keystore in OIOSAML has only one key.
But now I want to use separate keys for request signing and response encryption. It fails here.
Does OIOSAML support multiple keys in keystore?
If yes then how does it distinguish between signing and encryption keys?
This feature is available from OIOSAML release 3.
Related
I have a public key as:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAryQICCl6NZ5gDKrnSztO
3Hy8PEUcuyvg/ikC+VcIo2SFFSf18a3IMYldIugqqqZCs4/4uVW3sbdLs/6PfgdX
7O9D22ZiFWHPYA2k2N744MNiCD1UE+tJyllUhSblK48bn+v1oZHCM0nYQ2NqUkvS
j+hwUU3RiWl7x3D2s9wSdNt7XUtW05a/FXehsPSiJfKvHJJnGOX0BgTvkLnkAOTd
OrUZ/wK69Dzu4IvrN4vs9Nes8vbwPa/ddZEzGR0cQMt0JBkhk9kU/qwqUseP1QRJ
5I1jR4g8aYPL/ke9K35PxZWuDp3U0UPAZ3PjFAh+5T+fc7gzCs9dPzSHloruU+gl
FQIDAQAB
-----END PUBLIC KEY-------_mixed 009J33F94539089U_--
I don't understand what "--mixed 009J33F94539089U--" in the end is, and what it's purpose is.
This key is supposed to be used for creation of encrypted JWT, which is to be sent as payload to hit an API. I used this website to create encrypted JWT, but API hit fails when I use this generated encrypted JWT. But I had to remove this "--mixed 009J33F94539089U--" from my key while entering in the aforementioned website for the creation of encrypted JWT to be successful.
I am wondering if generating encrypted JWT without using this "--mixed 009J33F94539089U--" and using it as payload is causing the API hit to fail. What do I do about this?
[NOTE : The key I mentioned above isn't my actual key.]
I'm exhausted after looking for an answer for 3 days. I don't know if my suggested flow is wrong or my Google skills have really deteriorated.
My API needs to create a valid certificate from a CSR it received, by signing it with a private key that exists ONLY inside an HSM-like service (Azure KeyVault), which unfortunately doesn't offer Certificate Authority functions BUT does offer signing data with a key that exists there. My CA certificate's private key is stored in the HSM. I'm using ECDSA.
My suggested flow:
Client generates Key Pair + CSR and sends CSR to API
API creates a certificate from the CSR
API asks HSM to sign the CSR data and receives back a signature
API appends the signature to the certificate and returns a signed (and including CA in chain) certificate to the Client
I'm using C# .NET Core and would like to keep it cross-platform (as it runs in Linux containers), so I have to keep it as native as possible or using Bouncy Castle (which I'm still not sure if runs in Linux .NET Core).
I really appreciate your help!
I had faced a similar issue and found a solution. You'll have to use the PKCS11Interop.X509Store library.
The solution uses dotnet core native System.Security.Cryptography.X509Certificates.CertificateRequest::Create method
for generating a certificate.
As per the docs:
Pkcs11Interop is managed library written in C# that brings the
full power of PKCS#11 API to the .NET environment
Pkcs11Interop.X509Store is managed library built on top of
Pkcs11Interop. It's main goal is to provide easy to use PKCS#11 based
read-only X.509 certificate store that can be easily integrated with
standard .NET ecosystem.
Till v0.3.0, implementation for issuing a certificate (i.e signing a CSR) is not available.
With minor modifications in the PKCS11Interop library, I was able to sign the CSR.
Mentioned in Issue #30, the code is now added in the PKCS11Interop.X509Store library version 0.4.0.
The below code is taken from test cases for BasicEcdsaCertificateRequestTest. Test cases for RSA CertificateRequest are also there.
// Load PKCS#11 based store
using (var pkcs11Store = new Pkcs11X509Store(SoftHsm2Manager.LibraryPath, SoftHsm2Manager.PinProvider))
{
// Find signing certificate (CA certificate)
Pkcs11X509Certificate pkcs11CertOfCertificateAuthority = Helpers.GetCertificate(pkcs11Store, SoftHsm2Manager.Token1Label, SoftHsm2Manager.Token1TestUserEcdsaLabel);
// Generate new key pair for end entity
ECDsa ecKeyPairOfEndEntity = ECDsa.Create(ECCurve.NamedCurves.nistP256);
// Define certificate request
CertificateRequest certificateRequest = new CertificateRequest(
new X500DistinguishedName("C=SK,L=Bratislava,CN=BasicEcdsaCertificateRequestTest"),
ecKeyPairOfEndEntity,
HashAlgorithmName.SHA256);
// Define certificate extensions
certificateRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, true));
certificateRequest.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(certificateRequest.PublicKey, false));
certificateRequest.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature, false));
// Issue X.509 certificate for end entity
X509Certificate2 certificateOfEndEntity = certificateRequest.Create(
pkcs11CertOfCertificateAuthority.Info.ParsedCertificate.SubjectName,
X509SignatureGenerator.CreateForECDsa(pkcs11CertOfCertificateAuthority.GetECDsaPrivateKey()),
DateTimeOffset.UtcNow,
DateTimeOffset.UtcNow.AddDays(365),
new BigInteger(1).ToByteArray());
// Verify signature on X.509 certificate for end entity
Assert.IsTrue(CaCertSignedEndEntityCert(pkcs11CertOfCertificateAuthority.Info.ParsedCertificate.RawData, certificateOfEndEntity.RawData));
// Asociate end entity certificate with its private key
certificateOfEndEntity = certificateOfEndEntity.CopyWithPrivateKey(ecKeyPairOfEndEntity);
// Export end entity certificate to PKCS#12 file
string basePath = Helpers.GetBasePath();
string pkcs12FilePath = Path.Combine(basePath, "BasicEcdsaCertificateRequestTest.p12");
File.WriteAllBytes(pkcs12FilePath, certificateOfEndEntity.Export(X509ContentType.Pkcs12, "password"));
}
Hope this helps.
Here is my Signature Base String:
POST&https%3A%2F%2Faccount.api.here.com%2Foauth2%2Ftoken&grant_type%3Dclient_credentials%26oauth_consumer_key%3Dkey%26oauth_nonce%3D123456%26oauth_signature_method%3DHMAC-SHA256%26oauth_timestamp%3D1585591059%26oauth_version%3D1.0
Here is my signature:
kCGgrwFgEi85njS5WOeM88t0L70V99StMjxTXzYQEiI
Here is my Authorization Header
OAuth oauth_consumer_key="key",oauth_nonce="123456",oauth_timestamp="1585590864",oauth_signature_method="HMAC-SHA256",oauth_version="1.0",oauth_signature="kCGgrwFgEi85njS5WOeM88t0L70V99StMjxTXzYQEiI"
Here is the error:
{"errorId":"ERROR-f2dd0dcd-73e8-48e8-ae07-9d772e1b7399","httpStatus":401,"errorCode":401300,"message":"Signature mismatch. Authorization signature or client credential is wrong.","error":"invalid_client","error_description":"errorCode: '401300'. Signature mismatch. Authorization signature or client credential is wrong."}
James
The reason for signature mismatch is that the one you created is different than the one server created. Check the following –
Did you append ‘&’ at the end of access key secret to create signing
key
Did you convert the signing key and base string into bytes before
passing it to HMAC-SHA256 hashing algorithm
Did you convert the output of HMAC-SHA256 hashing algorithm into base64 string
Regarding error code, you can refer this - https://developer.here.com/documentation/authentication/dev_guide/topics/error-messages.html
We had a C# application connecting to SAP backend systemes using the SAPSSO technology. There has now been a need to replace this with X.509 certificates.
When using SAPSSO, the orginal code would make an HTTP call to the target system, and get a cookie containing the ticket to use:
response = (HttpWebResponse)request.GetResponse();
ticket = response.Cookies["MYSAPSSO2"].Value;
That ticket would then be passed to the RfcCustomDestination object to facilitate a secure connection:
prms.Add(RfcConfigParameters.SAPSSO2Ticket, ticket);
The problem is, I can change the enumerated value from SAPSSO2Ticket to X509Certificate,
prms.Add(RfcConfigParameters.X509Certificate, ticket);
but when I do this, no ticket can be returned from the response, since a MYSAPSSO2 cookie is no longer provided.
So how can I generate the needed ticket value for an X509 certificate?
According to here:
A digital certificate contains:
Serial Number: Used to uniquely identify the certificate.
Subject: The person, or entity identified.
Signature Algorithm: The algorithm used to create the signature.
Signature: The actual signature to verify that it came from the
issuer.
Issuer: The entity that verified the information and issued the
certificate.
Valid-From: The date the certificate is first valid from.
Valid-To: The expiration date.
Key-Usage: Purpose of the public key (e.g. encipherment, signature,
certificate signing...).
Public Key: The public key.
Thumbprint Algorithm: The algorithm used to hash the public key
certificate.
Thumbprint (also known as fingerprint): The hash itself, used as an
abbreviated form of the public key certificate.
My question is, how does the signature come from? I think it is used to ensure the digital certificate is issued by a trusted issuer. So the issuer use its private key to sign on something to produce the signature, then the verifier of the certificate must have the corresponding public key of the issuer to decipher the signature and verify that this something is genuine.
If I am correct, this something must be stored in the certificate as well for the verifier to compare the deciphered signature to. So what's this something? Could it be the thumbprint (hash) of the public key?
This something is most of the certificate itself. The receiver can calculate the hash over the TBSCertificate (the part of the certificate To Be Signed) itself using the algorithm in the certificate. The receiver can then verify that it is the same as the hash calculated by the signer (the issuer of the certificate). If the signature is verified and the signer is trusted, then the certificate is verified.
There are more tests to be performed such as validating that the certificate has not been revoked or over it's date of expiry before it can be fully trusted.
A digital certificate consists of:
certificate information
signature algorithm
signature value
See the RFC 5280 for more info on the exact structure of the certificate.