Verifying the password of generated x509 certificate - encryption

I have created a x509 certificate. There is a set of openssl commands I used to create it, for example the first command it:
openssl genrsa -passout pass:"$MYPWD" -out privkey.key 2048
where "$MYPWD" is an environment variable where I set the password. After executing this command, how would I check that the password is actually the value of MYPWD environment variable, and not just literally "$MYPWD"?
Thank you everyone in advance!

You must specify a cypher to encrypt the output.
openssl genrsa -aes256 -passout env:MYPWD -out privkey.key 2048
To verify that the password was actually set, simply read back the key:
openssl pkey -in privkey.key
You will see the password prompt.
You can also inspect the content of the privkey.key, "ENCRYPTED"... will be there.
cat privkey.key
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,3A2E02985A117F7266F9664420F685B2
...

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.

How to check the algorithm used in key generation using openssl genrsa output

I have create a keypair using
openssl genrsa -out test1.key
I want to verify how the key is encrypted, by looking at openssl genrsa --help ,
-des encrypt the generated key with DES in cbc mode
-des3 encrypt the generated key with DES in ede cbc mode (168 bit key)
--idea encrypt the generated key with IDEA in cbc mode
I used openssl rsa -in test1.key -text but it is not showing any information
about those.
Please if there is anyway to check that?
You're expecting an encrypted key, but it isn't by default. The genrsa man page clearly states (emphasis mine):
-aes128|-aes192|-aes256|-aria128|-aria192|-aria256|-camellia128|-camellia192|-camellia256|-des|-des3|-idea
These options encrypt the private key with specified cipher before
outputting it. If none of these options is specified no encryption
is used. If encryption is used a pass phrase is prompted for if it
is not supplied via the -passout argument.
This can also be seen from the generated PEM file which has no information other than the key itself:
$ openssl genrsa -out test-plain.key
Generating RSA private key, 2048 bit long modulus (2 primes)
...........................................................................................+++++
..........................+++++
e is 65537 (0x010001)
$ head -n 2 test-plain.key
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA5RCtTAg3fuspy1VdZpHqrFz4Lt9p5MnZkjH0FZ9wAk9vpvRF
On the other hand, if we specify an encryption algorithm to apply to the key, two things happen:
I am prompted for a password (unless specified through -passout)
the algorithm and block cipher mode is shown in the PEM output
$ openssl genrsa -out test-aes.key -aes128
Generating RSA private key, 2048 bit long modulus (2 primes)
............................................................+++++
................................+++++
e is 65537 (0x010001)
Enter pass phrase for test-aes.key: foobar
Verifying - Enter pass phrase for test-aes.key: foobar
$ head -n 3 test-aes.key
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,ED364325F65A0F212D07BC9E643D6424
We can clearly see that AES-128-CBC is being used with the indicated IV.

"No DEK-Info header in block" when attempting to read encrypted private key

I'm trying to read an encrypted PKCS8 private key file. I generated the keys like this:
openssl genrsa -out file.pem -passout pass:file -aes256 1024
openssl pkcs8 -topk8 -inform pem -in file.pem -outform pem -out filePKCS8.pem
And I try reading it in Go this way:
block, _ := pem.Decode(key)
return x509.DecryptPEMBlock(block, password)
But I get an error saying:
x509: no DEK-Info header in block
However, I can't figure out what's going wrong. Am I generating the key wrong or am I using the wrong library? I see libraries specifically for reading unencrypted PKCS8 files but none for encrypted PKCS8 files specifically.
Does anyone have any idea?
Go don't have function to decrypt PKCS8 keys in standard library.
You can this package:
https://github.com/youmark/pkcs8/blob/master/pkcs8.go#L103
A longer explaination for anyone with the same problem.
What would work
Your first command
openssl genrsa -out file.pem -passout pass:file -aes256 1024
generates a PKCS#1 private key file (file.pem):
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,1DA219DB746F88C6DDA0D852A0FD3232
AEf09rGkgGEJ79GgO4dEVsArwv4IbbODlxy95uHhfkdGYmuk6OlTpiCUE0GT68wn
KFJfBcHr8Z3VqiHGsXxM5QlKhgnfptxfbrdKErgBD5LQcrvnqmf43KeD4lGQcpiy
...
...
mAKMCwiU/GKZz8ZwQ4qGkBlVVCOFfgwmfbqguJF2l8yzM8lYI9MZ9NEwKkvEbc
-----END RSA PRIVATE KEY-----
This private key file can be parsed and decrypted by x509.DecryptPEMBlock() alright.
What would not work and why
Your second command
openssl pkcs8 -topk8 -inform pem -in file.pem -outform pem -out filePKCS8.pem
converts that file into PKCS#8 format (filePKCS8.pem).
The subcommmand genpkey would directly produce a similar result:
openssl genpkey -algorithm RSA -aes256 \
-pkeyopt rsa_keygen_bits:1024 -out filePKCS8.pem
The generated filePKCS8.pem (either way) would look similar to this:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIISrTBXBgkqhkiG9w0BBQ0wSjKpBgkqhkiG9w0BBQwwHAQIKL+ordsVfqsCAggB
MAwGCCqGSIb3DQIJCQAwHQYJYIZIWAUDBAEqBBCipOAAxWkC0/zkNLNYTSMgBIIS
...
...
zfdxjZ0XmPiwED2azsLMnRrWnRj2UqMtnv9zO/ucik9za
-----END ENCRYPTED PRIVATE KEY-----
x509.DecryptPEMBlock() does not support this format. And as specified in #8860, the Go's core library has no real plan to support pkcs#8 in the near future.
As mentioned by Gregory, if you want to work with it, you'll have better luck with 3rd party library like github.com/youmark/pkcs8 (Documentation).

openssl smime message signing

Here is how one should sign a message with openssl smime? according to the docs
openssl smime -sign -in in.txt -text -out mail.msg -signer mycert.pem \
-inkey mykey.pem -certfile mycerts.pem
But why is there a -signer key with a certificate -- isn't a private key passed in -inkey enough for message signing? Isn't it just a usual asymmetric encryption scheme, where my private key is for message signing and my certificate (i.e., signed public key corresponding to my private key) is for my counterpart to encrypt the message?
As far as I found out this is for the second side to verify your signature -- in case if it does not have that certificate.

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'

Resources