How to generate EC X509 certificate on unix? - 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

Related

Encrypt a file with a x509 certificate with cfssl and openssl

Noob question:
Given a x509 certificate created with cfssl:
server.pem
server-key.pem
issued by
ca.pem
Usages for server.pem are:
"server": {
...
"usages": [ "signing", "key encipherment", "server auth", "data encipherment", "s/mime" ]
...
},
I'm able to verify the certificate with openssl:
openssl verify -CAfile ca.pem server.pem
server.pem: OK
I'm able to sign a plain text file:
openssl dgst -sha256 -sign server-key.pem -out signable.txt.sha256 signable.txt
And verify the signature
openssl x509 -pubkey -noout -in server.pem | tee server-pubkey.pem
openssl dgst -sha256 -verify server-pubkey.pem -signature signable.txt.sha256 signable.txt
Verified OK
But now I can't find out how to use the certificate for encryption/decryption:
Attempt 1
openssl smime -encrypt -aes-256-cbc -in secret.txt -out secret.txt.enc -outform DER server-key.pem
Could not read recipient certificate file from server-key.pem
4027E4F7E97F0000:error:1608010C:STORE routines:ossl_store_handle_load_result:unsupported:../crypto/store/store_result.c:151:
Unable to load recipient certificate file
Attempt 2
openssl smime -encrypt -aes-256-cbc -in secret.txt -out secret.txt.enc -outform DER server.pem
Error creating PKCS#7 structure
40F7A87F027F0000:error:10800096:PKCS7 routines:PKCS7_RECIP_INFO_set:encryption not supported for this key type:../crypto/pkcs7/pk7_lib.c:637:
40F7A87F027F0000:error:10800078:PKCS7 routines:PKCS7_encrypt_ex:error adding recipient:../crypto/pkcs7/pk7_smime.c:467:
Attempt 3
cat server.pem server-key.pem > server.pkcs12
openssl smime -encrypt -aes-256-cbc -in secret.txt -out secret.txt.enc -outform DER server.pkcs12
Error creating PKCS#7 structure
40C7B2B9947F0000:error:10800096:PKCS7 routines:PKCS7_RECIP_INFO_set:encryption not supported for this key type:../crypto/pkcs7/pk7_lib.c:637:
40C7B2B9947F0000:error:10800078:PKCS7 routines:PKCS7_encrypt_ex:error adding recipient:../crypto/pkcs7/pk7_smime.c:467:
Any clue?
Meta: this is not about programming or development, and is out of scope for StackOverflow. However I can't fit the following in readable comments. I will delete if necessary to close or remove the question.
do openssl x509 -in server.pem -text -noout and look at the line Public Key Algorithm. If it says dsaEncryption (horrible name BTW) or rsassaPss you can't encrypt with this cert (and key); these algorithms do not support encryption.* If it says id-ecPublicKey the smime command (which as you can see in the error message actually does PKCS7) cannot use it to encrypt but the cms command can -- this is one of the few differences between PKCS7 and CMS (the addition of the KeyAgreeRecipInfo choice aka KARI).
* DSA was designed in an earlier century specifically to prevent encryption to allow its use without regard to then-current legal prohibition on exporting encryption 'technology' from the US. And also without regard to the Schnorr patent claims, but that's a more complicated story. Although RSA in general (and plain RSA keys) can be used for both signature and encryption, the PSS (Probabilistic Signature Scheme) variant is only defined for signature. There is a similar variant OAEP (Optimal Asymmetric Encryption Padding) for encryption but it does not use a different algorithm identifier in the certificate like PSS optionally does.
To encrypt in any of PKCS7/CMS/SMIME you only need the certificate, not the privatekey. (Technically to encrypt in any PKC you need the publickey, but PKCS7/CMS/SMIME use other data in the certificate in addition to the publickey.) You will generally need the privatekey and certificate to decrypt.
Concatenating two PEM files does not create a PKCS12 file, and naming such a file .pkcs12 is confusing, misleading, and deceptive to humans -- though the program ignores it.

PEM_read_bio_PUBKEY failed while sending signed SAMLRequest to Auth0

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"
}

Generate SignedData with Openssl console (with CRT)

I'm really new to openssl and I need to generate a CMS Signed Data Message,I was given a xml file with some data in it, and I have a CRT and my private key.
How do I generate the CMS Signed Data using the xml, crt and key?? How do I write the command in the console
I've been looking in the documentation but I'm lost.
openssl cms -sign -in data.xml -nodetach -inkey private.key -signer cert.crt -out result.cms -outform PEM

Creating RSA Private Key from PFX (PKCS #12) file

I'm trying to get a private RSA key from a pkcs #12 file.
I've tried running the standard
openssl pkcs12 -nocerts -out priv.pem -in domain.com.pfx
However this results in a key file like the one below:
Bag Attributes
Microsoft Local Key set: <No Values>
localKeyID: 01 00 00 00
friendlyName: xxxxxxxx
Microsoft CSP Name: Microsoft RSA SChannel Cryptographic Provider
Key Attributes
X509v3 Key Usage: 10
-----BEGIN ENCRYPTED PRIVATE KEY-----
The server that I need to put it into canot handle the key file, and when I look at the examples data I see a file like below
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,2CF27DD60B8BB3FF
And of cause the key is present in both files.
However it seems the server will only accept RSA Private key file, and it seems to me like the output I get is a X509v3 file, any one know how to get this to an RSA Private key file?
Well - using a text editor to remove the offending lines may be easiest. Otherwise below will clean up the bag attributes:
openssl pkcs12 -in x.pfx -nocerts -nodes -passin pass:123456 | openssl rsa -out privkey.pem
and can also be used to get der/net
openssl pkcs12 -in x-fred.p12 -nocerts -nodes -passin pass: | openssl rsa -outform DER -out privkey.der
which may be in fact the format you want. It is fairly common for tools to not accept a password less private key though (and a lot of tools will silently fail if the # of chars are not at least 4 or 6). So in those cases change the tailend to:
.... | openssl rsa -passout pass:123456 -out privkey.pem
.... | openssl rsa -passout pass:123456 -out privkey.der -outform der
On windows 7 64bit, you can simply use your command.But in mac and linux, you should do the following steps:
1, create your pem file:
openssl pkcs12 -in xxx.pfx -out xxx.pem
2, create your rsa private key :
openssl pkcs12 -in xxx.pfx -passin pass:yourpassword | openssl rsa -des3 -passout pass:yourpassowrd -out xxx.key
this step will create the key file with the conten:"
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,2CF27DD60B8BB3FF"
3, open your .pem and .key file in a text editor, and replace the origin key"
-----BEGIN ENCRYPTED PRIVATE KEY-----" in the .pem file
with the rsa key in the .key file.
This works for me:
openssl pkcs12 -in "$1" \
-nocerts -nomacver \
-passin file:<(cat "$pw") \
-passout file:<(cat "$pw") |
sed -n '/^-----BEGIN ENCRYPTED PRIVATE KEY-----/,/^-----END ENCRYPTED PRIVATE KEY-----/p'

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