Converting RSA public key from der to pub - rsa

I have a public RSA key in der format which I have to use as integration mechanism for encryption.
Problem is that when I am trying to use that key with node crypto library, it is throwing error. In the docs I am unable to find how to use der format.While trying to convert der file to pem using openssl command -
openssl rsa -RSAPublicKey_in -in m2p-test-public.der -inform DER -outform PEM -out m2p-test-public.pem -RSAPublicKey_out
It is throwing -
_out
unable to load Public Key
140477267113624:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1217:
140477267113624:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:386:Type=RSA
What am I doing wrong ?
Any help will be appreciated.
Adding output of ASN.1 decoding
SEQUENCE (2 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.2.840.113549.1.1.1 rsaEncryption (PKCS #1)
NULL
BIT STRING (1 elem)
SEQUENCE (2 elem)
INTEGER (2048 bit)
XXXXX
INTEGER YYYYY
Replaced numeric block with XXXX, YYYY

By default openssl is expecting a private key. As you are providing a public key you must specify -pubin and it will load correctly.
openssl rsa -pubin -in m2p-test-public.der -inform DER -outform PEM -out m2p-test-public.pem

Related

How can I decode tbsCertificate content?

I was trying to see what's the content of a tbsCerticate.
This is what I have done:
Download a certificate from website (baidu.com) in der binary format.
Use openssl x509 -in bd.cer -inform cer -text -noout >> bd.cer.noout.txt to translate into text. Now I can see what's in the certificate
openssl asn1parse -inform der -in bd.cer > bd.cer.asn1 parse the certificate. According to rfc5280, second line is tbsCertificate content, which is 4:d=1 hl=4 l=2326 cons: SEQUENCE.
dd if=bd.cer of=bd.cer.tbsCertificate skip=4 bs=1 count=2330 to dump the bytes.
openssl x509 -in bd.cer.tbsCertificate -inform der -text -noout >> bd.cer.tbs.txt Now I want to parse it bd.cer.tbsCertificate to x509 format to see it, but it failed.
unable to load certificate
140421447947392:error:0D0680A8:asn1 encoding routines:asn1_check_tlen:wrong tag:../crypto/asn1/tasn_dec.c:1149:
140421447947392:error:0D07803A:asn1 encoding routines:asn1_item_embed_d2i:nested asn1 error:../crypto/asn1/tasn_dec.c:309:Type=X509_CINF
140421447947392:error:0D08303A:asn1 encoding routines:asn1_template_noexp_d2i:nested asn1 error:../crypto/asn1/tasn_dec.c:646:Field=cert_info, Type=X509
I want to know why I can't translate the bd.cer.tbsCertificate into x509 just like bd.cer. Do I miss something? From the error, it seems that the structure is not right.
What should I do if I want to see tbsCertificate in txt to know what exactly are encrypted. Thank you for your help!
From the error, it seems that the structure is not right.
Correct. The x509 command can only read a Certificate.
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING }
TBSCertificate ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version MUST be v2 or v3
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version MUST be v2 or v3
extensions [3] EXPLICIT Extensions OPTIONAL
-- If present, version MUST be v3
}
Since you've provided a TBSCertificate, not a Certificate, when it expected to see SEQUENCE, SEQUENCE, but got SEQUENCE, [0], it errored out.
Nothing in ASN.1 DER encoding says "this structure is a TBSCertificate", the structure is just a definition of the order data should be written or read. So the openssl x509 command doesn't have any inkling that you've stripped off the outer SEQUENCE (the Certificate structure). openssl asn1parse shows what the data contains. "I'm a sequence, my content is this long. I'm a sequence, my content is this long. I'm a context-specific-0, my content is this long and it is 0x02. ..."
What should I do if I want to see tbsCertificate in txt to know what exactly are encrypted.
Nothing in the certificate is encrypted.
"TBSCertificate" is "to be signed certificate". The outer structure is { "all the contents", "how did it get signed", "the signature" }. The openssl x509 command on the certificate already showed you what was in the TBSCertificate value... the version number, subject, validity, issuer, etc.

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 ).

Sign a JWT with a SHA cert using jose4j

New to using jose4j. I have found examples like this to set private key from cert:
JsonWebSignature jws = new JsonWebSignature();
PKCS8EncodedKeySpec spec =
new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey pk = kf.generatePrivate(spec);
jws.setKey(kf.generatePrivate(spec));
But I get this error message
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
I think it is because the cert was created as SHA256 instead of RSA. Here is how I was told the cert was created:
openssl req -x509 -sha256 -nodes -days 730 -newkey rsa:2048 -keyout private.key -out certificate_pub.crt
Does anyone have any examples of how I could sign JWT with a SHA256 cert?
With additional info, that private key file is PEM but NOT PKCS#8, as a modern version of OpenSSL should have created for req -newkey. And the difference between PEM and "DER" (binary) which standard Java requires is not just removing (and adding) the BEGIN and END lines.
Your simplest solution if OpenSSL is available is to convert both of these, without encrypting:
openssl pkcs8 -topk8 -nocrypt -outform der -in private.pem -out good.der
Then read good.der (use better name if you like) as bytes, and put that in PKCS8EncodedKeySpec and use it as you posted. Aside: you don't need to fiddle with DataInputStream, which isn't really intended for "plain old" bytes; java.nio.file.Files.readAllBytes can open, allocate, and read for you.
The next more complicated alternative is to convert to PKCS#8 but still PEM: same as about but omit -outform der (and use a file name that indicates PEM, to avoid confusion). Then in Java read that file as characters (with a Reader, usually BufferedReader, not a Stream), discard the BEGIN and END lines, concatenate all the lines between, and convert them from base64 to byte[]: in Java8 you have java.util.Base64, before that you can use javax.xml.bind.DatatypeConverter.
To read the file you have in standard Java is harder. You could read the PEM-armored PKCS#1 and convert to binary PKCS#1, then "wrap" the PKCS#1 into PKCS#8 by building the DER encoding, but that's a good bit more complicated than what you've demonstrated familiarity with. Or you could parse the PKCS#1 and use the components to construct your own implemenation of RSAPrivateCrtKey and use that directly (no factory), ditto.
The other alternative is to use the third-party library from http://www.BouncyCastle.org which has more flexible features for handling PEM files than standard Java. But you need to learn their API as well as the standard one, and if your program will run anywhere else you need to ensure BC is deployed with or as part of your program.

OpenSSL error generating a CSR from a private key

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.