PEM_read_bio_PUBKEY failed while sending signed SAMLRequest to Auth0 - .net-core

I'm trying to sign the (ITfoxtec Identity SAML2) SAMLRequests and testing with Auth0 and I'm getting the following error on the Auth0 side:
invalid_request: PEM_read_bio_PUBKEY failed
I filled the public key in their config.
{
"signatureAlgorithm": "rsa-sha256",
"digestAlgorithm": "sha256",
"signingCert": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqt7eddg/N9MgaivTEWif\n...\nnmEbAFKJtjieiwu1JjsMsdUCAwEAAQ==\n-----END PUBLIC KEY-----\n"
}
Here is how I generated the keys:
openssl req -x509 -sha256 -newkey rsa:4096 -keyout auth0samlprivate.key -out auth0samlpublic.pem -days 3650 -nodes -subj "/CN=mydomain.com"
# then i generate the public key to fill in the configuration of Auth0
openssl x509 -pubkey -noout -in auth0samlpublic.pem > auth0samlpublickey.pem
# then I generate the .pfx file to use server side for the private key
openssl pkcs12 -export -out auth0saml.pfx -inkey auth0samlprivate.key -in auth0samlpublic.cer
Then in the code:
config.SignAuthnRequest = true;
config.SigningCertificate = CertificateUtil.Load("Path/To/auth0saml.pfx", "myPassword");
In the browser, I get redirected to the right URL that contains a Signature query parameter, so it seems to be handled correctly but Auth0 doesn't seem to be able to read it.
What did I miss? I'm new to the certificate part of it.

The issue was about the generated certificate.
First, although the example in Auth0 is using a private key, using certificate is fine too.
The following commands worked fine for me:
openssl req -x509 -sha256 -newkey rsa:2048 -keyout auth0samlprivate.pem -out auth0samlpublic.pem -days 3650 -nodes -subj "/CN=thefiftyapp.com"
openssl pkcs12 -export -in auth0samlpublic.pem -inkey auth0samlprivate.pem -out auth0saml.pfx
I think the real issue was about changing manually the pem file to a cer file without using a command line.
And the Auth0 config:
{
"signatureAlgorithm": "rsa-sha256",
"digestAlgorithm": "sha256",
"signingCert": "-----BEGIN CERTIFICATE-----\nMIIDFTCCAf2gAwIBAgIUXg1jHZ9qRIrtySCsF/bK2JvYxMQwDQYJKoZIhvcNAQEL\n...\n53f63eKJn9PMmyqIYl9/K48ABR3Bf8exfvK4HRudkSU66pQsj8biIxl4MSDMg/6G\naHUZoTBJbJ/sXmoExGpltvFDcNMITfJMKGFCIBO9VnlsJrXdwalSTpxg/9Yi79GD\n5yMXEjicqion8KE0LMsk93LVS92bkujhSg==\n-----END CERTIFICATE-----\n"
}

Related

How to encrypt/decrypt text file in openssl using a key in DER format

I get the error message in OpenSSL when trying to encrypt a text file with my public key in DER format: "unable to load Public Key"
The command I currently use in Windows CMD is:
openssl rsautl -pubin -keyform der -inkey certificate.der -encrypt -in textplane.txt -out textplane_enc.txt
And the content I am trying to encrypt is similar to the following:
In the first row has a maximum of 312 characters
In the second row has a maximum of 457 characters
And in the third row has a maximum of 35 characters
I understand that you can see a problem because of the size of this, and that is that I have solved it in C# and perform a separation every certain amount of bytes, but on the other side they would have to use my same structure and it is not like that, on the other side they directly use OpenSSL.
The command they gave me to generate my keys and .DER are:
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 730 -out certificate.pem
openssl x509 -in certificate.pem -outform DER -out certificate.der
I really appreciate the help in advance, it's my first post and I hope to be clear.

How to generate EC X509 certificate on unix?

I need to generate X509 certificate using EC.
What are the commands that I need to perform in order to achieve a PEM file of this certificate?
First, you need to create a private key with the elliptic curve of your choice:
openssl ecparam -name <curve> -param_enc explicit -genkey -out key.pem
You can find all supported curves with openssl ecparam -list_curves.
Afterwards you can create your certificate request, e.g.:
openssl req -x509 -new -key key.pem -out certificate.pem

import encrypted private key to jks

I need use ssl(2 way handshake) socket for connection in my project.
So for creating keys, i used openssl with this comands :
for server :
req -x509 -days 3650 -nodes -newkey rsa:2048 -keyout a_private.key -out a_certificate.cert
rsa -in a_private.key -des3 -out a_private_des.key
rsa -in a_private_des.key -pubout -out a_pub.key
for client :
req -x509 -days 3650 -nodes -newkey rsa:2048 -keyout b_private.key -out b_certificate.cert
rsa -in b_private.key -des3 -out b_private_des.key
rsa -in b_private_des.key -pubout -out b_pub.key
for import to jks file i used keytool:
keytool -import -alias a_private -file a_private_des.key -keystore a.jks
keytool error: java.lang.Exception: Input not an X.509 certificate
after that, I made der file with this command :
pkcs8 -topk8 -in a_private_des.key -out a_private_des.der -outform DER
and retry to import key to jks file:
keytool -import -alias a_private -file a_private_des.der -keystore a.jks
keytool error: java.lang.Exception: Input not an X.509 certificate
and I get same exception with b_pub.key
how can I import encrypted private key and public key in jks file ?
tanx alot.
To import a key pair (key and cert) into a java keystore, you first need to create a p12 file. Whilst the question is "import encrypted private key to jks", I don't actually believe the key in question is encrypted as the "nodes" option is used.
So to import a key, and cert into a JKS use:
# create p12
openssl pkcs12 -export \
-name a_private \
-out a_private.p12 \
-inkey a_private.key \
-in a_certificate.cert \
-passin "pass:changeit" \
-passout "pass:changeit"
# create jks
keytool -v -importkeystore -deststoretype pkcs12 -destkeystore \
"a.jks" \
-srckeystore "a_private.p12" -srcstoretype pkcs12 \
-alias "a_private" -srcstorepass "changeit" \
-deststorepass "changeit" -destkeypass "changeit"
Actually change the password "changeit" as well.
I believe the -import option only let's you import certificates, not keys. Looking at this post it seems you may have to write some kind of workaround.

Create .pem file for Google Manage Domains

I used this code
# Generate the RSA keys and certificate
openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj \
'/C=US/ST=CA/L=Mountain View/CN=www.example.com' -keyout \
myrsakey.pem -out /tmp/myrsacert.pem
From here:
http://code.google.com/apis/gdata/docs/auth/authsub.html#Registered
Google links to this from their own ManageDomains site. I have used the code, and uploaded the pem file to Google. When I test it, it gives me this error:
SyntaxError: Missing PEM Prefix
Can anyone point me in the right direction, I've wasted several hours on this.
Thanks!
You have to send myrsacert.pem to Google, not myrsakey.pem !
The file has to contain:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
source code:
start = s.find("-----BEGIN CERTIFICATE-----")
end = s.find("-----END CERTIFICATE-----")
if start == -1:
raise SyntaxError("Missing PEM prefix")

How can I encrypt data with a public key in Node.js? [duplicate]

This question already has answers here:
Encrypting data with a public key in Node.js
(6 answers)
Closed 2 years ago.
In crypto, I see only Signer/Verifier for doing digital signature and Cipher/Decipher with symmetric key encryption.
How do I encrypt data with public key?
As mentioned in the official nodejs api docs here:
crypto.publicEncrypt(key, buffer)
Encrypts the content of buffer with key and returns a new Buffer with encrypted content. The returned data can be decrypted using the corresponding private key, for example using crypto.privateDecrypt().
If key is not a KeyObject, this function behaves as if key had been
passed to crypto.createPublicKey(). If it is an object, the padding
property can be passed. Otherwise, this function uses
RSA_PKCS1_OAEP_PADDING.
Because RSA public keys can be derived from private keys, a private
key may be passed instead of a public key.
So the answer is:
var encrypted = crypto.publicEncrypt(publicKey, buffer);
You might be interested in my NaCl bindings. From its API:
// Encrypt and sign
box(message, nonce, pubkey, privkey)
// Decrypt and validate
unbox(box, nonce, pubkey, privkey)
// Generates a new keypair, returns {private: <buffer>, public: <buffer>}
boxKeypair()
// Lengths of nonces and public and private keys in bytes
// { nonce: x, pubkey: x, privkey: x }
lengths.box
Yet another approach is using Cryptographic Message Syntax (CMS). It's not a pure Node.js solution, but you likely have all tools you need in the box. Below is the example using OpenSSL:
Generate x509 certificate (recipient) and private key files (in Bash):
openssl req -nodes -new -x509 -keyout key.pem -out cert.pem
Encrypt/Decrypt message from standard input (in Bash):
echo 123 | openssl cms -encrypt -recip cert.pem | openssl cms -decrypt -inkey key.pem
You can use -in/-out parameters to work with files. Below is an example you can use for Node.js:
require('child_process').execSync("openssl cms -encrypt -in file.json -recip cert.pem -out file.json.cms")
On Linux you'll likely have OpenSSL installed already. You can get OpenSSL on Windows by installing Git Bash, although you can also use built-in PowerShell commands. You'll need to generate a PFX certificate (using New-SelfSignedCertificate) or install existing one (can be generated with OpenSSL too). Once the certificate installed in the certificate store, you can use below commands for encryption/decryption:
Protect-CmsMessage -to CN=MyCertName -Path file.json -OutFile file.json.cms
Unprotect-CmsMessage -Path file.json # It will find proper cert in cert store for you
Below is an example how to generate .pem and PFX certificates from the same private key using OpenSSL, and make messages interchangeable between OpenSSL and PowerShell.
Generate certificate with extensions (that's required on Windows):
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout key.pem -out cert.pem -subj '/CN=MyCertName' -addext extendedKeyUsage=1.3.6.1.4.1.311.80.1 -addext keyUsage=keyEncipherment
The above snippet will work only for newer versions of OpenSSL (1.1.1). Otherwise you need a separate file to define extensions. Then generate a PFX certificate (protect it with some password):
openssl pkcs12 -export -out certificate.pfx -inkey key.pem -in cert.pem -passout pass:P#ssw0rd
Then copy that PFX file to your Windows machine. You should be able to install it via PowerShell (Import-PfxCertificate) or manually (click on it and follow wizard, use all defaults). In order to make messages interchangeable use the -inform \ -outform parameter when using OpenSSL. For example:
openssl cms -encrypt -in file.json -recip cert.pem -outform PEM
openssl cms -decrypt -in file.json.cms -inkey key.pem -inform PEM
# If having both OpenSSL/PowerShell on the same OS, use this for testing:
echo test | Protect-CmsMessage -to CN=MyCertName | openssl cms -decrypt -inform PEM -inkey key.pem
Btw, the CmsMessage commands will be available on PowerShell Core 7.1, so you can use it on Linux/Mac too (it's in preview now, and a stable version will be released in Dec 2020).

Resources