I am currently working on integrating Single Sign-On (SSO) functionality into an existing application using the SAML Java toolkit. The Identity Provider (IdP) I am working with requires me to have both a signing certificate and an encryption certificate. As per the documentation, I need to sign the AuthnRequest using my SP-SAML-Sign-key and validate the response using the IdP-SAML-Sign-key, while also decrypting it using my SP-SAML-Enc-Key. In my current testing environment, I have generated self-signed certificates for both signing and encryption/decryption purposes. The issue I am facing is in configuring the SAML Java Toolkit (https://github.com/SAML-Toolkits/java-saml/blob/master/samples/java-saml-tookit-jspsample/src/main/resources/onelogin.saml.properties) as I am only able to load the private key and certificate for signature. However, I have been unable to find a property that allows me to provide my encryption-key.
To provide the private key and the certificate for signature, I using the following properties:
# Usually x509cert and privateKey of the SP are provided by files placed at
# the certs folder. But we can also provide them with the following parameters
onelogin.saml2.sp.x509cert =
# Requires Format PKCS#8 BEGIN PRIVATE KEY
# If you have PKCS#1 BEGIN RSA PRIVATE KEY convert it by openssl pkcs8 -topk8 -inform pem -nocrypt -in sp.rsa_key -outform pem -out sp.pem
onelogin.saml2.sp.privatekey
To use the pubic certificate of the IdP, I am using the following property:
# Public x509 certificate of the IdP
onelogin.saml2.idp.x509cert =
Since I did not find any property that can allow me to use my private key, I decided to delve into the code of SAML Java Toolkit. I strategically placed breakpoints in the library and I see that we compute the signature of a SAML-AuthnRequest and decrypt a SAML-Response with the same key (this.settings.getSPKey()) loaded using the property onelogin.saml2.sp.privatekey.I see no possiblity to use a different private key.
As a final attempt, I considered extending the class SamlResponse and introduced a new class SamlResponseExt. In the constructor of the child class, I passed in my decryption key. My goal was to override the loadXmlFromBase64() method and use the key within it. Unfortunately, the private key variable was not initialized with my key value as the method was executed in the constructor of the superclass before making the initialization.
Is it a missing feature or have I simply overlooked the option for using different keys in the SAML Java Toolkit?
Related
I am facing the following issue. I am currently working on integrating Single Sign-On (SSO) functionality into an existing application using the SAML Java toolkit. The Identity Provider (IdP) I am working with requires me to have an encryption certificate that uses the RSA-encryption schema RSA-OAEP (Rivest–Shamir–Adleman - Optimal asymmetric encryption padding). For testing purposes, It is allowed to use self signed certificates. Since I have already generated a signature certificate with the cryptographic signature scheme PSS, so I have tried to use RSA_PADDING_MODE:OAEP (by analogy to RSA_PADDING_MODE:PSS) but it did not work. I used the following command to create a private key.
openssl genpkey -algorithm RSA -out privateKey.pem -pkeyopt rsa_keygen_bits:4096 -pkeyopt rsa_padding_mode:oaep
I get the following error
I have the last version of openssl (OpenSSL 1.1.1s) installed on my computer. Since I did not find any explanation for this error. I tried to read the documentation of openSSL and I found out that RSA-OAEP is only used for the encryption and decryption:
Based on the documentation of OpenSSL, It seems that I should generate a private key and a self signed certificate using RSA without padding. The IdP will pad the message using OAEP padding schema. Then it will encrypt the SAML-message with my public certificate that I have provided. On my side, I will decrypt the SAML-message using my private key. Finally, I should unpad the message using a Java library. Am I correct ?
I would like to generate a certificate, public key, private key and all other things needed in order to connect Windows Azure via java code. I prefer using only keytool.
How do I do that?
The java code requires a JKS file with private key in it.
Thx!
Keytool can help you up to certain extent however combination of Keytool and OpenSSL will give you everything you need to have your Java based application connect to Windows Azure (both management portal as well as SSL enabled Web Application.
Please follow the documentation as Migrating Keys from 'keytool' to 'OpenSSL'
Using "keytool" to generate a private and public key pair.
Using "keytool" to export the self-signed certificate from PrivateKeyEntry.
Using "keytool" to display details of a certificate.
Using "OpenSSL" to view certificate exported by "keytool".
Writing "DumpKey.java" to dump key pair out of "keytool" keystore files.
Using "OpenSSL" to convert dumped key pair from binary to Base64 encoding.
Using "OpenSSL" to view key pair dumped and converted from "keytool" keystore files.
I need to encrypt and sign data using PKCS7(CMS).
I am using bouncy castle provided api to achieve this using java .
Till now what i understood is i need to follow these steps
Need to generate a key pair private & public key using some algorithm say RSA
Certify it with X509 certificate
Convert it into PKCS7 key format like p7b
Generate java key store using keytool some *.jks file
Generate the Certificate Signing Request (CSR) using keytool command *.crt
Become self CA(Certificate Autority) and certify
Import key from keystore created in previous stem and encrypt sign and decrypt data
I still need to figure out what steps i need to follow to sign,encrypt,decrypt data.
My question is
Is my steps are correct ?
How do i certify key pair generated by RSA algorithm and convert into PKCS7 key format
How do i become self CA and certify
I got this to encrypt and sign, still i am confused with steps to follow and also most of them are deprecated.
What you need is not BouncyCastle.
You need OpenSSL and a guide.
OpenSSL
How to set up your own certificate authority
How to create a self-signed certificate
How to use a certificate in Java
Alternatively, to generate and store an RSA key using Java:
Generate RSA key pair and encode private as string
Suppose I have an application which in some way retrieves a client certificate (private/public key pair) at runtime via a secure channel (so I don't have this client certificate at build time).
How can I use this client certificate for client authentication without using keytool and not using some on persistent/ondisk keystore. So I do not want (actually I can't) to import it using a command line keytool?
Actually I want to replicate the functionality done in libcurl. You just set the client certificate (with private key) and your done. It doesn't involve a keystore.
All this has to be done in Java/Android.
You can do it in Java by defining your own KeyManager as described in the JSSE Reference Guide. I can't speak for Android.
I just got this working and I dont think you'll be very happy with my answer but it does work :)
So the hard part is to get the pkcs12 certificate you need to perform client authentication, if your certificate is already in pkcs12 then you've got all the hard stuff out of the way and you can refer to the second answer on SSL client authentication in Android to see how to use that certificate.
if you just have a public private key pair and not a pkcs12 certificate then you will need to make one. As far as I could tell there is no way in java/android to create this certificate so you need to use the android NDK and openssl.
if you download the openssl-android project from https://github.com/guardianproject/openssl-android you can use it to build openssl. By default it compiles as a .so shared object but only some of the android devices I tried to run this code on were able to link against libcrypto, so, although im sure there is a better way I went into the Android.mk files and replaced include $(BUILD_SHARED_LIBRARY) with include $(BUILD_STATIC_LIBRARY) in a few places so that I could compile a .a static library.
I then used the info from Android NDK: Link using a pre-compiled static library to link the libcrypto.a I compiled to my native code.
This native code uses openssl to first create an X509 certificate and then uses it to create a PKCS12 file which can be used in the manner I mentioned before located at SSL client authentication in Android
first you need to get your public and private keys into native land as EVP_PKEY pointers which can happen in a variety of ways based on what format your keys are in then you can use the following code to create an X509 certificate
X509 *public_key_cert = X509_new();
X509_gmtime_adj(X509_get_notBefore(public_key_cert),0);
X509_gmtime_adj(X509_get_notAfter(public_key_cert), (long) 60*60*24*365);
X509_set_pubkey(public_key_cert,evp_pub_key);
This creates the most minimally valid X509 certificate which is valid for 1 year. You may want to do other stuff like sign the certificate if you are going to run your own certificate authority, or set any of a large set of headers which contain various bits of information.
next you need to create the pkcs12 certificate using the X509 cert like this:
PKCS12 *pkcs12 = PKCS12_create(password, "Some Sort of Friendly Name", evp_priv_key, public_key_cert, NULL, 0, 0, 0, 0, 0);
password is a char* containing the password which will be used to encrypt the private key using triple-DES
Now that you have a pkcs12 certificate you can go over to SSL client authentication in Android and get client authentication going.
Good Luck!
I'm interested in Java-NSS libraries, and I'm reading the Sun's P11 Guide. I am confused on the following:
What is the difference between using a PKCS12 keystore and a PKCS11 keystore?
A keystore is just a keystore, right? Are there some differences? Can they be used interchangeably in any aspect?
PKCS#12 is a file format (often called .p12 or .pfx) where you can store a private key and certificates. It's used for converting/transporting keys and certificates, mainly. If you export a private key + certificate from your browser, it's likely going to be in that format.
PKCS#11 is an interface, usually used to talk to hardware cryptographic tokens (often smart-cards or USB-tokens, which effectively are smart-cards embedded in a reader). This interface has a number of operations to make use of the keys and certificates. Some tokens are able to sign using the private key they contain, without the key being able to leave the device.
The point of this interface is to treat what handles the keys and certificates as a separate entity, without having to do the cryptographic operations that PKCS#11 offer (more specifically, the ones related to the private key).
When you use PKCS#11 with NSS, you're effectively using NSS as a black-box wrapped behind the PKCS#11 layer (it's effectively a software provider for what a PKCS#11 hardware token would be). There is a slight difference in the way Java uses NSS via PKCS#11 in that it doesn't require a PKCS#11 shared library (compared to other PKCS#11 libraries), so as such, it's not PKCS#11 strictly speaking, although it's very similar.
In Java, you may be able to get an RSAPrivateKey instance from a PKCS#11 store, use it to sign and decipher, without ever being able to get anything from its modulus. The security provider handling it will do the signing/deciphering via the library (and thus via the token, if that library is supported by a hardware token).
Coming back to the KeyStore in Java, it's an API that can allow you to load and use keys and certificates from files (you get various files formats such as JKS, PKCS#12, PEM, depending on your security provider) or from other underlying APIs (such as PKCS#11, more or less merged with NSS in the Sun provider, or the KeychainStore if you're on OSX and want to use the KeyChain as a KeyStore).
From Different types of keystore in Java -- Overview, the differences between PKCS12 and PKCS11 can be described as following
PKCS12, this is a standard keystore type which can be used in Java and
other languages. You can find this keystore implementation at
sun.security.pkcs12.PKCS12KeyStore. It usually has an extension of p12
or pfx. You can store private keys, secret keys and certificates on
this type. Unlike JKS, the private keys on PKCS12 keystore can be
extracted in Java. This type is portable and can be operated with
other libraries written in other languages such as C, C++ or C#.
Currently the default keystore type in Java is JKS, i.e the keystore
format will be JKS if you don't specify the -storetype while creating
keystore with keytool. However, the default keystore type will be
changed to PKCS12 in Java 9 because its enhanced compatibility
compared to JKS. You can check the default keystore type at
$JRE/lib/security/java.security file:
PKCS11, this is a hardware keystore type. It provides an interface for
the Java library to connect with hardware keystore devices such as
SafeNet's Luna, nCipher or Smart cards. You can find this
implementation at sun.security.pkcs11.P11KeyStore. When you load the
keystore, you no need to create a specific provider with specific
configuration. This keystore can store private keys, secret keys and
certificates. When loading the keystore, the entries will be retrieved
from the keystore and then converted into software entries.