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
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 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?
Background: What Works
From time to time we have to use a piece of Java software that reads PKCS#12 keystores. For this particular project, we have to create public/private pairs on an as-needed basis, and we store the keys in PKCS12 files because it's stable and pretty much everything can read that format.
Because we do a lot of Java in-house, we have keytool sitting around, and so we figured hey, just use keytool to create the private key and certificate. A typical instance looks like this:
keytool -keystore MyLuggage.p12 -storepass 123456 -storetype pkcs12
-alias "......"
-genkeypair -keyalg RSA -keysize typically_2048_or_3072 -sigalg SHA256withRSA
-ext "KeyUsage=dataEncipherment,digitalSignature,keyEncipherment"
-startdate ....
-dname "......."
The actual -keysize varies between 2048 and 8192 in practice; for the purposes of this question it hasn't seemed to make a difference what gets used, but obviously we use key lengths appropriate to the task if we get to choose them at all (usually dictated by the constraints of other software, or dictated by some regulation that's handed to us).
This has always worked, in that other software -- including the Java software mentioned at the start -- can read the keystore and make use of the private keys within. (And the public key can be exported and used, etc.)
Here's What Breaks
The software recently got upgraded to a version that uses the FIPS 140 certified Java libraries from RSA. ("BSAFE" or "JSAFE" depending on who you ask.) And now, trying to open previously-created PKCS#12 files fails with
java.lang.SecurityException: Algorithm not allowable in FIPS140 mode: PBE/PKCS12/SHA1/RC2/CBC/40
at ......
at java.security.KeyStore.load(Unknown Source)
The elided ...... frames are in the RSA source that we don't have and looks to use function names that have been obfuscated in any case. So looking at their source to try and figure out what exactly it's testing to cause this, isn't an option.
So, what is causing this? The only algorithms we've chosen are the "RSA" key generation and "SHA256withRSA" signature, both of which are permitted by FIPS 140-2. I've been looking again through keytool -genkeypair -help output and there don't seem to be any other algorithm or security options. (We've avoided using -keypass because PKCS#12 tools really hate it when the keystore password and the key password are different, and keytool -genkeypair defaults the key password to the keystore password.) The rest of the error message is confusing, as we don't specify the use of SHA-1 or RC2 (!) anywhere.
Googling around points to people having trouble with creating SSL certificates, which we're not doing here, and the solutions given seem to be specific to Tomcat.
Is this a problem with how we're creating the keystore, how we're creating the key pair in the keystore, or some "feature" of FIPS 140 that we haven't previously encountered?
PKCS#12 stores the private key encrypted with a password derived key. It looks like keytool uses pbeWithSHAAnd128BitRC2-CBC (pkcs-12PbeIds 5), an PBES1 algorithm for doing so. Even the keytool.exe of Oracle Java 9 does use this algorithm as you can verify by uploading a .p12 file to the online ASN.1 decoder decoding a sample PKCS#12 file.
If I read the PKCS#12 standard correctly PBES1 was long ago superseeded by the "newer" version of the key derivation system named "PBES2" (mostly PBKDF2 based) with should be used instead. But keytool does not make use of it. This is my interpretation of the error message.
Therefore the certificate and the key may be acceptable, but the PKCS#12 container is not acceptable. You may try to extract key and certificate and save them in a new PKCS#12 file using a current software like OpenSSL (or you simply generate the whole PKCS#12 file directly using OpenSSL).
OpenSSL has the option to specify the PBE used for key and certificate encryption (parameters -keypbe and -certpbe in PKCS#12 mode). I have not checked it but and algorithm like AES-256-CBC should be FIPS140 compatible.
I'm successfully signing a x509v3 certificate from a CSR using BouncyCastle in Java, but I have a problem: the string format from some of the certificate fields (Subject in this case) is UTF8_STRING and I need it to be PRINTABLE_STRING
When generating the certificate I use an X509v3CertificateBuilder and a CertificateFactory objects plus a JcaX509ExtensionUtils to add some extensions to it.
Any help on how to do this?
Thanks in advance.
I am trying to store a proxy X.509 certificate into a keystore. The certificate is generated using bouncycastle library, the problem is that I do not have the secret key for the certificate and from what I understand is that to store it in a Java key store I need the secret key. Furthermore I can't seem to convert the certificate into Java's own implementation of it.
I want to store it in a keystore so that Axis2's Rampart could attach it to SOAP messages according to our own security architecture.
IF anyone can kindly explain to me if there is a way to do this or if I am missing something important I would be thankful
from what I understand is that to store it in a Java key store I need the secret key
No. You don't need the private key to store a certificate. You only need that for your own certificate. Just use keytool -import.