I am trying to generate a encrytpted private/public key using the code example given here
https://docs.snowflake.com/en/user-guide/key-pair-auth.html
$ openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8
however it just generates an empty file. Is there something I'm missing perhaps?
Any tips would be appreciated
I am currently framing the openssl commands as a string and using linux system call int system(const char *command); for signing and verifying certain files.
For generating sha i use below command.
openssl dgst -sha256 > test_sha256.txt
After generating test_sha256.txt, i will sign this with my CA , which gives me signature.p7s, from which i extract CRLs(asn1parse -inform DER and dd ) and combining CRLs with my root CA, then i verify using below command.
openssl cms -verify -inform DER -in signature.p7s -binary -content test_sha256.txt -CAfile combined_CA.pem -purpose any -signer signer_file.crt
How can we achieve the same thing using the openssl library calls? Do we have separate openssl functions to achieve sign & verify.
When using public key cryptography, it is often customary to store private keys in an encrypted format, since they are of course supposed to be a secret. This is reflected in the OpenSSL C API, which provides functions like PEM_write_PrivateKey, which takes as function arguments an optional cipher to use to encrypt the key (like AES). Then, when reading the encrypted key back in from disk, the OpenSSL API provides functions like PEM_read_PrivateKey, which allows the user to provide a function pointer used as a callback so the application can provide OpenSSL with the password for the encrypted key.
But what confuses me is that the OpenSSL API also seems to let the user provide a password callback when reading in a Public key. For example, one API function signature for reading in a public key is:
EVP_PKEY *PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x,
pem_password_cb *cb, void *u);
So what is the purpose of providing a password callback when reading in a public key? AFAIK it makes no sense to encrypt a public key, since a public key is by definition supposed to be available to the general public. So why does the OpenSSL API have a function parameter here that takes a password callback?
As mentioned in this comment, any PEM-encoded data can be encrypted. Message encryption for privacy-enhanced mail (PEM) is defined in RFC 1421 and in the context of your question, it is interesting to look at the example message in
section 4.6 Summary of Encapsulated Header Fields
-----BEGIN PRIVACY-ENHANCED MESSAGE-----
Proc-Type: 4,ENCRYPTED
Content-Domain: RFC822
DEK-Info: DES-CBC,F8143EDE5960C597
Originator-ID-Symmetric: linn#zendia.enet.dec.com,,
Recipient-ID-Symmetric: linn#zendia.enet.dec.com,ptf-kmc,3
Key-Info: DES-ECB,RSA-MD2,9FD3AAD2F2691B9A,
B70665BB9BF7CBCDA60195DB94F727D3
Recipient-ID-Symmetric: pem-dev#tis.com,ptf-kmc,4
Key-Info: DES-ECB,RSA-MD2,161A3F75DC82EF26,
E2EF532C65CBCFF79F83A2658132DB47
LLrHB0eJzyhP+/fSStdW8okeEnv47jxe7SJ/iN72ohNcUk2jHEUSoH1nvNSIWL9M
8tEjmF/zxB+bATMtPjCUWbz8Lr9wloXIkjHUlBLpvXR0UrUzYbkNpk0agV2IzUpk
J6UiRRGcDSvzrsoK+oNvqu6z7Xs5Xfz5rDqUcMlK1Z6720dcBWGGsDLpTpSCnpot
dXd/H5LMDWnonNvPCwQUHt==
-----END PRIVACY-ENHANCED MESSAGE-----
Looking at the 1.1 branch of OpenSSL it has a function PEM_read_bio() that supports reading such a message and splitting it into its name (as given in the top line), header (the name-value pairs below that) and data (the base64-encoded stuff):
int PEM_read_bio(BIO *in, char **name, char **header,
unsigned char **data, long *len);
All OpenSSL PEM_read_XYZ() functions at some point invoke it, from PEM_bytes_read_bio(), because they are all implemented in the same way by means of macro expansions. That function contains the following calls:
PEM_read_bio(bp, &nm, &header, &data, &len)
to split the message, then
PEM_get_EVP_CIPHER_INFO(header, &cipher);
to figure out which type of encryption information is found in the header of that message and fill an EVP_CIPHER_INFO object with it, and then
PEM_do_header(&cipher, data, &len, cb, u);
to do the decryption of the data based on the cipher information found -- again if needed. Note the cb parameter which stands for callback, a mechanism to get input for any passphrase if needed.
Now what might be confusing, is that certain private key formats, like for example PKCS#8, also have their own mechanism of storing encryption information independent of the PEM encoding. Technically speaking, it should be possible to apply encryption to such keys twice: once at the PEM level and once at the PKCS#8 level. The OpenSSL tools for generating or converting to PKCS#8 formatted keys do not seem to offer that option though. Also, none of the tools seem to expose the option of encrypting any generated public key PEM files, unless a private key is included as well.
You can check some of the outputs to see if they match my story. First, generating an RSA key pair to a PKCS#1 format, nothing encrypted:
$ openssl genrsa
Generating RSA private key, 2048 bit long modulus (2 primes)
.................+++++
............+++++
e is 65537 (0x010001)
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAlcnR/w7zPoLrhuqFvcfz5fn8DFb0fEcCKOKSj+x+JJxGth9P
rJbxkt4pRXxbMIL0fX59HN5bRvQh2g59l/kfr30kCOnclap9nRrohWyg2i7720Cw
<truncated>
Then the same command, but using encryption, which happens at the PEM level, as you can see in the headers:
$ openssl genrsa -des3
Generating RSA private key, 2048 bit long modulus (2 primes)
.....................+++++
....................+++++
e is 65537 (0x010001)
Enter pass phrase:
Verifying - Enter pass phrase:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,D90861647707F687
DIupLghCjcvpLenqAAULaJj1EDvUUfc2Xc58YVh7rMTSVgLwZ+9CtnUQJcup4aUQ
a1EdGXTadwBQB2jTtiFJbH67/5D26PHXPnM+YN2rnoReOExVS7hKu3DTq7c4j6a3
<truncated>
Finally generating a similar key but now to PKCS#8, which has its own encryption and therefore does not get encrypted at the PEM level. You can see that the PEM headers are not there.
$ openssl genpkey -algorithm RSA -des3
.........................................+++++
...........................................................................+++++
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIV0Ih4bsI6egCAggA
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECNOim8HAN8j5BIIEyEe05hHtc8HL
<truncated>
If all my reasoning is correct, then the prompt "Enter PEM pass phrase" is inaccurate since this is not a PEM-level encryption but a PKCS#8-level encryption.
I'm very new to OpenSSL (been using it for literally two days). I'm using OpenSSL version 1.0.1, and I'm trying to implement OpenSSL functions to extract a particular x509 OID from an ASN.1 (DER-encoded) signedData Package (in particular, the OID is 2.16.840.1.101.2.1.2.78.2, id-ct-KP-encryptedKeyPkg). Just for now, I'm only trying to have a program that can extract this data from the package given any ASN.1 encoded package. I'm able to encode the certificate into a buffer using the following code:
#include <openssl/x509.h>
int main()
{
/* for brevity, please assume "encrypted" points to a DER-encoded buffer */
char* encrypted = malloc( 3000 );
int sizeOfEncrypted = 3000; // assume this number is correct
BIO* bp = BIO_new( BIO_s_mem() );
ASN1_parse( bp, (unsigned char*) encrypted, (long) encryptedSize, 4 );
BUF_MEM *bptr;
BIO_get_mem_ptr( bp, &bptr );
BIO_set_close( bp, BIO_NOCLOSE );
BIO_free( bp );
return 0;
}
If I write the bytes of the buffer pointed to by "bptr" to a file, I get all the fields of the encoded data, similar to the output of:
$ openssl asn1parse -inform DER -in my_pkg.dat -i
I've confirmed the data is correct, but now as I mentioned, I'm looking for the correct OpenSSL instructions to extract a particular OID (so instead of X509_get_version(), it would be something like X509_get_encryptedKeyPkg(), per se, for a particular OID). How can I do this? I can write code that just searches for the OID in the cert and can potentially parse the data I need, but I'm almost certain/hoping OpenSSL has the tools to do that already, and more reliably. Once again, I'm an OpenSSL noobie, so I'm looking as best as I can for the solution on the internet, but perhaps I'm not using the right wording. Please let me know if you can help me out. Thanks!
I am experimenting with using libtomcrypt to do RSA-2048 bit encryption. My current objective is to import a public key from a file. This file was generated using OpenSSL with the command:
$ openssl rsa -in private.pem -outform PEM -pubout -out public.pem
So I believe my public key is in PKCS#1 padding and in OpenSSL's PEM format.
I believe the function I need to use is rsa_import(), but that takes an in buffer, a length, and outputs an rsa_key pointer. Just to be clear, I believe what I need to do is as follows:
Read in the contents of public.pem to a buffer
Toss out the Header and Footers containing "Begin Public Key" etc.
Decode data from base64.
Pass in resulting data to rsa_import.
Is this correct? Can anyone who has used libtomcrypt for this purpose comment on this? Thanks.
So, upon digging into the source of rsa_import(), I figured out pretty quickly that it was expecting the key to be in DER format. Since I had access to the private key, I just made a DER file using this openssl command:
openssl rsa -in private.pem -outform DER -pubout -out public.der
Notably the argument for -outform is now DER rather than PEM. After this, I just read the file contents into a char buffer, then passed that in as the main argument for rsa_import. After that rsa_import made the key no problem and I was able to encrypt/decrypt from there.