OpenSSL error generating a CSR from a private key - app-store

I have got a private key that I have exported from our .p12 file. The key has been used to successfully sign the application itself.
Now I need to generate a CSR from the key. This site advises using the following command for the task:
req -out CSR.csr -key privateKey.key -new
This yields the following error:
unable to load Private Key
6420:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:.\crypto\asn1\tasn_dec.c:1319:
6420:error:0D06C03A:asn1 encoding routines:ASN1_D2I_EX_PRIMITIVE:nested asn1 error:.\crypto\asn1\tasn_dec.c:831:
6420:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:.\crypto\asn1\tasn_dec.c:751:Field=version, Type=RSA
6420:error:04093004:rsa routines:OLD_RSA_PRIV_DECODE:RSA lib:.\crypto\rsa\rsa_ameth.c:115:
6420:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:.\crypto\asn1\tasn_dec.c:1319:
6420:error:0D06C03A:asn1 encoding routines:ASN1_D2I_EX_PRIMITIVE:nested asn1 error:.\crypto\asn1\tasn_dec.c:831:
6420:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:.\crypto\asn1\tasn_dec.c:751:Field=version, Type=PKCS8_PRIV_KEY_INFO
6420:error:0907B00D:PEM routines:PEM_READ_BIO_PRIVATEKEY:ASN1 lib:.\crypto\pem\pem_pkey.c:132:
error in req
The error is the same as if I try
rsa -noout -text -in privateKey.key
The file does exist. What am I doing wrong and how can I fix it?

An alternative solution that did work.
1, Create a .pem file from the original .p12 (enter password when prompted)
openssl pkcs12 -in my.p12 -nocerts -out my.pem -nodes
2, Create the request from the .pem:
openssl req -new -key my.pem -out my.csr
You will be prompted to enter country, state, locality, organisation, unit and common names and your e-mail address, and extra attributes (challenge password and optional company name).
Done.
EDIT: also on CERN Certificate Authority's Prepare renewal certificate signing request(CSR) with OpenSSL.

Related

How to hash256 and digitally sign (with a private key) a string in Powershell

Using openssl I generated a private key (let's say httpCert.key) and a self signed certificate. Now, I have a string which I want to hash256, digitally sign with my private key i.e. httpCert.key and do a base64 encoding.
I can do this all in bash using openssl as below:
signature=`printf "test" | openssl dgst -sha256 -sign httpCert.key | openssl base64 -A`
But struggling to find a way to do this in Powershell.
Based on a help from other post, I can do a simple hash and encode as below:
$hasher=[System.Security.Cryptography.HashAlgorithm]::Create('sha256')
$signSHA=$hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes("test"))
$signature=[Convert]::ToBase64String($signSHA)
But not sure how to sign the hash256 with a private key. I tried using "System.Security.Cryptography.RSACryptoServiceProvider" but couldn't get it working.
$Certificate = [Security.Cryptography.X509Certificates.X509Certificate2]::new("g:\Drive\ff.pfx","")
$data=[System.Text.Encoding]::UTF8.GetBytes("test")
$sData=$Certificate.PrivateKey.SignData($Data,'SHA1')
[Convert]::ToBase64String($sData)

Unable to determine DKIM key length

I created a public and private key running ssh-keygen -t rsa -b 4096.
I then created a DNS entry dkim._domainkey of type TXT with this value:
v=dkim1; p=AAAAB3NzaC1yc2EAAAABIwAAAgEAvQ1GCaGx9CRKqW4wJUalTb6lGb6C1vm5iTUaus7b8EfurN8JWQouVa+n7V1YbbtAk14om7k+24i5ApbaULv8bhH5fGyano91ZQ4UpXTNxo9TrpgLntRCVQf0GlB1JNADiFMHetepf49xMDh5+NhPvgxzDBwGNqa2e4dR+SiruFKUNr5kBeLCzB9mcpzgI0jLj3PVfiB0c+SfeCcQUcGteWplurl3KLWdFAEAkTlMHPd61adt//mGRy9+XbKnVUVUNK6bn5k5pV+CSmx31pSbbFbUUjtmS4gUzPuqFDsJlVv0Sz5THNMgNiei4dSX3EqvJUmE13m+sKhImyqLoIFMTxD2Z2PxOVVqE2IqnEi9Hn+QluEiczi/g9/thWz8AnodDLlDv884LSQK7Dedie35ueyzUwgkeUsnebzSdqk1A0AqF/IcEBFiAyQyjepJ03Svv04job4cMjX90L4WoeznyCu2KTo9mTcoRRZJhLlDu0afcKavLOr6ydpJyaEsxgRzZURxFbPXUq8FGR3MbuOLszToHd6+CAOH5exRRll+Bs8O8I/dQsvJA6NqCQpynjXpNRwZ5e3RqshOR8RlZsNB4fuTk0SN2rNiozxAwQWoCl4dg+u/jfyki1GPD86qo1U1NWWXKIpXHZqYSx4FXI/CVkQ3KLI9LW1U1GxPwGVpqkU
Now when I test it using https://protodave.com/tools/dkim-key-checker/ it says:
Unable to properly parse the public key string and determine key length or the key is invalid. Tip: Make sure there aren't any special charaters or newlines pasted into your key in the TXT record.
I just copy pasted the complete key out of the file that was generated by ssh-keygen. Any tips on how I can figure out what went wrong?
I used openssl genrsa -out openssl.priv 1024 and openssl rsa -in openssl.priv -pubout >openssl.pub to generate the keys and now it works just fine.
You can and maybe should use keylength of 2048, it's in the DKIM spec.
That said, I heard of problems with mail servers hosted by AWS, insisting on 1024, but that was a few years back.
Create private key:
$openssl genrsa -out dkim_private.pem 2048
Pull out public key in der form, for encoding without LFs subsequently:
$openssl rsa -in dkim_private.pem -pubout -outform der -out dkim_public.key
Convert public key to base64 representation required:
$openssl <dkim_public.key base64 -A >p_equals
After this, the base64 encoded string in file p_equals is the string needed in your DNS TXT record (p=MI......AB ).

Country Name field in CA generated by openssl is encoded as PRINTABLESTRING while other fields are UTF8STRING

I am generating a CA certificate with openssl version 1.0.1e with the following commands:
openssl ecparam -out ec_key.pem -name secp384r1 -genkey
openssl req -new -key ec_key.pem -x509 -nodes -days 1460 -out ec_ca_cert.pem
At the end of this process I enter DN fields as follow:
Country Name (2 letter code) [AU]:US
State or Province Name (Full Name) [Some-State]:Florida
Locality Name (eg, city)[]:Miami
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Coca Cola
Organization Unit Name (eg, section) []:Drinks
Common Name (e.g. server FQDN or YOUR name) []:Miki
Email Address []:
I convert the ec_ca_cert.pem certificate to DER format:
openssl x509 -in ec_ca_cert.pem -inform PEM -out ec_ca_cert.der -outform DER
When I edit the ec_ca_cert.der file with an HEX editor, I can clearly see that the Country field is encoded as PRINTABLESTRING (Type=0x13) while all the other fields (Locality Name, Organization Name, Organization Unit Name, Common Name) are encoded as UTF8STRING (Type=0x0c).
Is there a reason for this, or is there a problem in my process, or an openssl issue?
I got the following answer in openssl-users forum:
"countryName is ALWAYS a PrintableString, and is ALWAYS 2 characters long.
See X.520 for a normative definition, included in RFC5280 for information.
"

deleting x.509 v3 extensions from issued certificate

I need to make light weight PKC for that i want to delete x509 v3 extensions from the user certificate. May i use this openssl command to delete v3 extensions?
openssl x509 -in /usr/local/openca/var/openca/crypto/certs/E841B2655206FA6A3ADA.pem -noout -text -certopt no_extensions -out /usr/local/openca/var/openca/crypto/certs/ -out
E841B2655206FA6A3ADA_nov3ext.pem
or where should i make changes to generate x509 v1 certificate since it doesn't contain x509 extensions. could you please provide me a link for the reference.
thanks for your time.
Usually (well, virtually always really!) the signature does not just cover the distinguished name on the cert; but everything else as well (serial, expiry dates, etc).
So while it is not hard to cut down the certificate to size - it will instantly invalidate the signature by its issuer.
However - in some cases it is possible to do something else - and that is dispense/ignore the signature part of the cert completely; and just focus on the public key.
Use someting like
cat somecert.pem | openssl x509 -pubkey -nout
to get just the public key. So forego all of X509 and in essense no longer have a PKI. Just pairs of raw public keys and private keys.
Then in your application commit the fairly unforgivable gaffe of inventing your own crypto - and have the owner of that public key sign something like a NONCE with its private key; and validate the signature. E.g.
# the 'server' sends a nonce to the client
openssl rand -base64 128 > send-to-client
then on the client it is signed
cat msg-from-server | openssl pkeyutl -inkey privkey.pem -sign | base64 > send-to-server
and on the server we check this
cat msg-from-client | openssl pkeyutl -in pubkey-of-client.pem -verify
and take things form there. However unless you are a kick-ass cryptographer and protocol designer, schemes like this (and above certainly does!) are riddled with flaws and pitfalls.
But in theory it does let you use just a few 1000 bytes of RSA keys; or a few 100 bytes of Elliptic curve based keys.

Can SSL cert be used to digitally sign files?

I want to ask a thing about digital signing I am not very sure.
Instead of creating a self signed certificate to use to sign some (PDF) files, I wanted to take my SSL cert which have my data already verified.
But the question is: Can a SSL cert be used to digital sign files or is it incompatible in some manner?
EDIT: To clarify, this question is not about how to sign PDFs, is only about if a SSL cert can be used (or converted in any way) to sign files.
To support digital signing certificate must have digitalSignature option in it's keyUsage field (and codeSigning option in it's extendedKeyUsage field if your want to sign programs with it).
Signing may be done with existing tools or manually (java example, you are not asking for it, but this code snippet might be useful anyway):
byte[] bytesToSign = loadMyData();
KeyStore ks = KeyStore.getInstance("pkcs12", "SunJSSE");
ks.load(new FileInputStream("cert.p12"), "passwd1".toCharArray());
PrivateKey privateKey = (PrivateKey) ks.getKey("myalias", "passwd2".toCharArray());
Signature sig = Signature.getInstance("SHA1withRSA", ks.getProvider());
sig.initSign(privateKey);
sig.update(bytesToSign);
byte[] signature = sig.sign();
To make your own not self-signed certificate with openssl see this SO answer.
Also curious about signing PDF's - aren't separate hash sums of these files enough in your case?
edit: if you want any sign, not exactly X.509 sign by existing tools, you can extract RSA key from your cert and do signing without bothering about keyUsage field.
At the core, the certificate is just a normal RSA public key that's been signed by several authorities.
So yes, definitely possible.
Though I don't know of any easy-to-use widespread tools for the end-user for this.
Yes, you can sign and verify the signature of files using SSL certificates
Here is an example:
SSLCERT='/XXXX/ssl/certs/fqdn.pem'
SSLKEY='/XXXX/ssl/private_keys/fqdn.pem'
# You might not need to specify a CA
CACERTFILE='/XXXX/ssl/certs/ca.pem'
# File to sign
FILE='YYYYYYY'
# Signs, needs ${SSLKEY} and ${FILE}
openssl dgst -sha512 -sign ${SSLKEY} -out ${FILE}.sha512 ${FILE}
# Then transfer the following files to another server:
# - ${CACERTFILE}
# - ${SSLCERT}
# - ${FILE}
# - ${FILE}.sha512
# Check the certificate is valid
openssl verify -verbose -CAfile ${CACERTFILE} ${SSLCERT}
# Extract the pub key from the cert
openssl x509 -in ${SSLCERT} -pubkey -noout > ${SSLCERT}.pub
# Check the signature
openssl dgst -sha512 -verify ${SSLCERT}.pub -signature ${FILE}.sha512 ${FILE}