verifying a file signature with openssl dgst - cryptography

I am signing packets in some Java code and I want to verify the signatures on a C server. I want to fork openssl for this purpose (can always use library functions later... when I know openssl can verify the signatures); however, it's failing to do so:
openssl dgst -verify cert.pem -signature file.sha1 file.data
all it says is "unable to load key file"
The certificate says:
openssl verify cert.pem
cert.pem: /C=....
error 20 at 0 depth lookup:unable to get local issuer certificate
However, I specifically don't care about verifying the certificate, I want only to verify the signature for a given file!
The output of openssl x509 -in cert.pem -noout -text is:
Certificate:
Data:
Version: 1 (0x0)
Serial Number:
...
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=...
Validity
Not Before: Feb 1 15:22:44 2010 GMT
Not After : Jun 19 15:22:44 2037 GMT
Subject: C=...
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:cc:cc:f9:c7:3a:00:0f:07:90:55:d9:fb:a9:fe:
...
32:cc:ee:7f:f2:01:c7:35:d2:b5:9b:35:dd:69:76:
00:a9
Exponent: 65537 (0x10001)
Signature Algorithm: sha1WithRSAEncryption
39:d6:2c:6b:6a:00:74:b5:81:c2:b8:60:d6:6b:54:11:41:8d:
...
8f:3e:3f:5d:b3:f8:dd:5e

openssl dgst -verify foo.pem expects that foo.pem contains the "raw" public key in PEM format. The raw format is an encoding of a SubjectPublicKeyInfo structure, which can be found within a certificate; but openssl dgst cannot process a complete certificate in one go.
You must first extract the public key from the certificate:
openssl x509 -pubkey -noout -in cert.pem > pubkey.pem
then use the key to verify the signature:
openssl dgst -verify pubkey.pem -signature sigfile datafile

Related

OpenSSL: How to match if certificate and private key matches

I've an certificate and a p12 private key.
I need to check if both match:
$ openssl rsa -modulus -noout -in visor.p12 | openssl md5
unable to load Private Key
139755626676672:error:0909006C:PEM routines:get_name:no start line:../crypto/pem/pem_lib.c:745:Expecting: ANY PRIVATE KEY
$ openssl x509 –noout –modulus –in EC_SECPUBLIC.cer | openssl md5
x509: Unknown parameter –noout
x509: Use -help for summary.
(stdin)= d41d8cd98f00b204e9800998ecf8427e
Any ideas?

Not sure if self-signed ECDSA certificate generated programmatically complies for use with WebRTC and if fingerprint computation is correct

As should be clear, I am a newbie to certificates and cryptography in general.
I am trying to generate self-signed certificates programmatically for use with WebRTC in the implementation of a SFU. The RFC at Section 4.9, on the subject of certificates used for WebRTC, states:
The following values MUST be supported by a user agent: { name:
"RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new
Uint8Array([1, 0, 1]), hash: "SHA-256" }, and { name: "ECDSA",
namedCurve: "P-256" }.
After creating an ECDSA cert programmatically in C and saving it, I run the following command on the certificate file created:
openssl x509 -in /tmp/ecdsa_certificate -text #Linux command-line
I get the output:
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 1 (0x1)
Signature Algorithm: ecdsa-with-SHA256
Issuer: C = IN, O = XYZ Tech., CN = localhost
Validity
Not Before: Jun 23 17:28:14 2020 GMT
Not After : Jun 23 17:28:14 2021 GMT
Subject: C = IN, O = XYZ Tech., CN = localhost
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:d9:c8:cc:93:13:54:3d:e6:40:d7:2f:33:da:f2:
d4:e4:62:83:a4:ec:ad:98:f5:d5:2e:cf:3b:e8:5f:
ad:da:b9:e0:59:f0:19:59:84:b8:47:45:b4:21:56:
30:c8:1d:0b:9b:2d:02:e2:f5:4d:c7:57:2e:e6:a6:
f9:c4:c4:a7:5c
ASN1 OID: secp256k1
Signature Algorithm: ecdsa-with-SHA256
30:44:02:20:58:0a:49:7d:e3:0f:d7:56:6a:5c:af:f8:bd:1d:
5e:54:bb:15:10:ec:05:3a:3a:db:79:8f:e6:70:86:6d:3d:f1:
02:20:4f:89:5f:df:21:46:1b:da:6b:40:04:98:2c:df:35:ff:
e5:3d:52:d5:07:76:bf:23:a4:01:b7:28:bf:f5:83:30
-----BEGIN CERTIFICATE-----
MIIBTTCB9QIBATAKBggqhkjOPQQDAjA1MQswCQYDVQQGEwJJTjESMBAGA1UECgwJ
WFlaIFRlY2guMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjAwNjIzMTcyODE0WhcN
MjEwNjIzMTcyODE0WjA1MQswCQYDVQQGEwJJTjESMBAGA1UECgwJWFlaIFRlY2gu
MRIwEAYDVQQDDAlsb2NhbGhvc3QwVjAQBgcqhkjOPQIBBgUrgQQACgNCAATZyMyT
E1Q95kDXLzPa8tTkYoOk7K2Y9dUuzzvoX63aueBZ8BlZhLhHRbQhVjDIHQubLQLi
9U3HVy7mpvnExKdcMAoGCCqGSM49BAMCA0cAMEQCIFgKSX3jD9dWalyv+L0dXlS7
FRDsBTo623mP5nCGbT3xAiBPiV/fIUYb2mtABJgs3zX/5T1S1Qd2vyOkAbcov/WD
MA==
-----END CERTIFICATE-----
Does this certificate comply with the requirements of WebRTC for DTLS handshaking. It appears that only the public key and the fingerprint of the certificate matters for WebRTC usage.
Question 2:
I tried to compute the fingerprint over the certificate using the following function:
if (X509_digest(certificate, EVP_sha256(), rfingerprint, &fingerprintSize) !=0 )
printf("Error in X509_digest\n");
printf("finger print size is %d\n", fingerprintSize);
It displays a fingerprint size of only 7! In most of the SDPs I see that the fingerprint attribute is a lot longer. Any comments?
When working on Pion I was in the same boat as you asinix :) This is what I use to generate locally when testing WebRTC stuff.
openssl ecparam -out key.pem -name prime256v1 -genkey
openssl req -new -sha256 -key key.pem -out server.csr
openssl x509 -req -sha256 -days 365 -in server.csr -signkey key.pem -out cert.pem
If you get stuck you can also do RSA! Maybe just to unblock you on building your MVP :)
The implementation is Pure Go now, but you can see the first version where we did CGO here
I am not sure where your stuff differs, but feel free to copy/compare (no attribution needed)!

Extracting certificate parts to sign file with OpenSSL

I wish to sign a .mobileconfig file using the following command:
openssl smime \
-sign \
-signer your-cert.pem \
-inkey your-priv-key.pem \
-certfile TheCertChain.pem \
-nodetach \
-outform der \
-in ConfigProfile.mobileconfig \
-out ConfigProfile_signed.mobileconfig
I have an SSL certificate which was requested and installed on my machine, and a code-signing certificate which was requested and installed on my machine.
Now which certificate should I be using (code signing or SSL?), and how do I get hold of the your-cert.pem,your-priv-key.pem and TheCertChain.pem files?
Visiting GoDaddy again just gives me a single .pem file, and I do not know which one that even is.
Running openssl x509 -in godaddy.pem -inform pem -noout -text on the .pem from GoDaddy gives the following:
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 0 (0x0)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
Validity
Not Before: Jun 29 17:06:20 2004 GMT
Not After : Jun 29 17:06:20 2034 GMT
Subject: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:de:9d:d7:ea:57:18:49:a1:5b:eb:d7:5f:48:86:
ea:be:dd:ff:e4:ef:67:1c:f4:65:68:b3:57:71:a0:
****REMOVED FOR BREVITY****
58:c6:44:7b:0a:3e:62:28:5f:ba:41:07:53:58:cf:
11:7e:38:74:c5:f8:ff:b5:69:90:8f:84:74:ea:97:
1b:af
Exponent: 3 (0x3)
X509v3 extensions:
X509v3 Subject Key Identifier:
D2:C4:****REMOVED FOR BREVITY****:A8:6A:D4:E3
X509v3 Authority Key Identifier:
keyid:D2:C4:****REMOVED FOR BREVITY****D:A8:6A:D4:E3
DirName:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
serial:00
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: sha1WithRSAEncryption
32:4b:f3:b2:ca:3e:91:fc:12:c6:a1:07:8c:8e:77:a0:33:06:
14:5c:90:1e:18:f7:08:a6:3d:0a:19:f9:87:80:11:6e:69:e4:
96:17:30:ff:34:91:63:72:38:ee:cc:1c:01:a3:1d:94:28:a4:
****REMOVED FOR BREVITY****
10:43:a6:a5:9e:0a:d5:95:62:9a:0d:cf:88:82:c5:32:0c:e4:
2b:9f:45:e6:0d:9f:28:9c:b1:b9:2a:5a:57:ad:37:0f:af:1d:
7f:db:bd:9f
You'll need to sign with your private key, cert, and chain.
your-cert.pem is the certificate that GoDaddy issued you.
your-priv-key.pem is the private key you generated on your keychain or on the command line to create the CSR.
TheCertChain.pem is GoDaddy's certificate chain, you can find that on their website
FYI here's example code on how I'm signing a .mobileconfig in Ruby https://github.com/AppBlade/TestHub/blob/master/app/controllers/devices_controller.rb#L31

openssl x509 - what is trusted and rejected uses of SSL certificate?

When using OpenSSL utils for signing .csr request, its possible to use "openssl ca" util and "openssl x509" util.
Openssl ca's text config file has all needed x509 options like keyUsage, extendedKeyUsage.
Openssl x509's command line has options -addtrust and -addreject. When you sign a certificate with those options, you can see them later in "openssl x509 -text" output, something like:
user#inet-pc:~$ openssl x509 -req -in test.csr -CA ca.crt -CAkey ca.key -set_serial 1 -out test.crt -setalias "zzzz test alias" -addtrust emailProtection -addreject serverAuth
^ signing test.csr using own CA key and cert
user#inet-pc:~$ openssl x509 -text -in test.crt -nooutCertificate:
Data:
Version: 1 (0x0)
Serial Number: 1 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=RU, ST=Some-State, O=Internet Widgits Pty Ltd, OU=sdds, CN=ca
Validity
Not Before: Apr 23 06:24:58 2013 GMT
Not After : May 23 06:24:58 2013 GMT
Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=test
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
(huge text here)
Exponent: 65537 (0x10001)
Signature Algorithm: sha1WithRSAEncryption
(huge text here)
Trusted Uses:
E-mail Protection
Rejected Uses:
TLS Web Server Authentication
Alias: zzzz test alias
^ Trusted and Rejected uses. What are those uses for and how do they work? Why I cannot find any mention of them in X509 RFC5280? How to use "openssl ca" to add same trusted/rejected uses? What about "clientAuth" usage? It isnt listed in "trusted" or "rejected" - will this certificate be trusted by most common applications?
Update 1: OpenSSL's x509 manual says that "trust" settings are valid for OpenSSL's "verify" util, but what is that util for? Can invalid "trust" settings cause verification fail by usual http browsers/etc?
You need to look at the section 4.2.1.12 "Extended Key Usage" of the rfc5280 :
https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.12
Edit:
You are right, I am afraid I read your question too quickly. The trust settings are an OpenSSL auxiliary information, which as far as I know is stil experimental. See :
https://www.openssl.org/docs/apps/x509.html#TRUST_SETTINGS
Again, I am sorry for my previous answer.

Digital signature for a file using openssl

Is there a way to digitally sign a x509 certificate or any document using openssl?
To Generate Private Key
openssl genrsa -out privatekey.pem 2048
To Sign
openssl dgst -sha256 -sign privatekey.pem -out data.txt.signature data.txt
To Generate The Public Key
dgst -verify requires the public key
openssl rsa -in privatekey.pem -outform PEM -pubout -out publickey.pem
To Verify
openssl dgst -sha256 -verify publickey.pem -signature data.txt.signature data.txt
In case of success: prints "Verified OK", return code 0
In case of failure: prints "Verification Failure", return code 1
Yes, the dgst and rsautl component of OpenSSL can be used to compute a signature given an RSA key pair.
Signing:
openssl dgst -sha256 data.txt > hash
openssl rsautl -sign -inkey privatekey.pem -keyform PEM -in hash >signature
Verifying just the signature:
openssl rsautl -verify -inkey publickey.pem -pubin -keyform PEM -in signature
Update: Capturing Reto's comments from below because this is an important nuance. Presumably if you are going to the trouble to verify, you want to know the signature was produced on the plaintext to which it is attached:
This might sound obvious for some but: Be aware, rsautl verify just decrypts the file signature. The output of this call is guaranteed to be produced by the owner of the private key, but beside that nothing else is being checked. So to actually verify the consistency of data.txt you have to regenerate the digest and then compare it against the output of openssl rsautl -verify.
Verifying that the owner of the private key does vouch for data.txt:
openssl dgst -sha256 -verify publickey.pem -signature signature data.txt
For this operation, openssl requires the public key, the signature, and the message.
To digitally sign document in openssl it will work
For this first your certificate should be trusted
it would be look like this
-----BEGIN TRUSTED CERTIFICATE-----
MIIDbjCCAlYCCQCOyunl25ProDANBgkqhkiG9w0BAQUFADB5MQswCQYDVQQGEwJJ
...
-----END TRUSTED CERTIFICATE-----
Then use following command
smime -sign -signer certificate.pem -inkey private.key -in test.txt \
-out test1.txt -from ashish -to singhal