Is the CSR encrypted withe the private key? - ssl

Is the CSR(Certificate Signing Request) containing the public key and the organization details encrypted with the private key?
-If yes, How does the certificate Authority decrypt it, as the public key in the CSR is also encrypted?
-If no, How can the CA be sure that the CSR issuer has the private key?

The structure of CSR is defined in PKCS #10 that is re-published as RFC 2986
CSR includes, among other things, the public key of the requestor. The CA needs to verify that the requestor does hold the corresponding private key. To ensure the ownership of the private key the requestor signs the CSR's data with it's private key.
When CA receives a CSR, it extracts the public key of the requestor and validates the signature. If validation fais, the CSR is rejected.
The Wikipedia page includes a sample CSR with field-by-field decomposition. The sample is a request for a certificate with RSA public key and is signed using md5WithRSAEncryption algorithm.

Is the CSR(Certificate Signing Request) containing the public key and the organization details encrypted with the private key?
It is easy to check that it isn't.
1) Create a private key and associated CSR:
openssl req -new -sha256 -newkey rsa:2048 -nodes -keyout example.key -out example.csr
2) I now have 2 files, the private key and the CSR.
Let us show the content of the CSR after having deleted the private key, just to make sure it is not needed, and comparing with the private key.
With private key still there:
$ openssl req -noout -text -in example.csr
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:e2:23:3c:4e:d8:39:ce:9a:16:2f:e2:ef:e7:9b:
5d:7f:20:a7:9a:4b:dd:54:ad:6b:b3:ff:33:78:65:
f2:b1:e1:e3:b5:eb:23:9d:da:b3:8d:3c:2f:1f:60:
9a:17:36:df:0f:4e:3a:bd:fb:9f:73:d5:00:c2:65:
04:a2:77:e6:5b:27:f2:30:8f:57:31:c8:bf:d1:0a:
cc:db:f5:95:8e:98:ff:34:c5:ed:68:57:f8:43:47:
41:ff:cb:6d:27:ae:de:33:95:cd:d6:0a:f8:0b:25:
27:99:4e:6b:7d:d8:c4:dd:83:97:57:7a:42:69:4c:
41:e2:d6:7f:86:d0:6f:1b:c2:30:b2:e7:a9:ee:5b:
9d:a1:ce:80:ec:45:a6:ad:a4:6e:b1:6a:b1:68:ef:
c4:7d:5b:6c:e5:24:fe:54:f9:bb:09:48:5c:49:ca:
fe:41:28:bc:48:e8:02:bf:ac:b0:5b:c6:3f:bb:0e:
17:d4:31:02:31:27:b1:a3:7a:ff:82:49:f0:11:10:
64:53:44:ca:61:82:fd:3a:82:5c:07:48:23:1f:db:
e5:0f:64:79:09:19:25:b4:a5:07:42:d3:b4:54:75:
61:13:43:63:34:a2:72:55:07:d6:d1:8c:74:31:cb:
5c:54:1e:6a:e7:04:86:35:4c:d9:a4:31:3f:fd:36:
9c:59
Exponent: 65537 (0x10001)
Attributes:
a0:00
Signature Algorithm: sha256WithRSAEncryption
6d:fb:a6:e5:2b:89:5c:ef:5c:ca:cc:d3:9a:3d:b1:c1:41:9d:
b5:55:ca:2c:17:ca:ea:74:1d:79:b9:16:ec:81:08:95:94:98:
e1:2b:50:c7:46:eb:d4:97:09:25:cc:da:b4:bd:34:3c:5a:14:
c8:88:ed:21:99:63:e9:c0:0e:fa:bb:5d:a7:27:11:22:61:a1:
1f:d3:65:c8:cc:14:ff:d7:ce:19:29:14:67:ed:e5:b8:31:b5:
25:55:8e:59:42:f1:2a:6d:f9:fe:4a:be:08:b9:23:c5:b6:3b:
c8:7e:3f:0c:bd:bb:37:f6:fd:5a:0e:50:50:43:8e:59:f7:b6:
77:06:50:b2:45:2a:17:f4:53:5a:7c:3c:50:6d:de:74:e3:0e:
df:94:48:bc:a9:fa:b8:a1:9a:3e:dc:10:c8:50:cb:9b:a7:49:
cc:ac:88:66:54:e6:d3:06:81:95:f4:ac:e1:61:d7:88:18:74:
e8:8e:d2:8d:e9:71:7f:99:41:b9:b3:a1:ad:af:d6:0b:2f:46:
8d:fa:c4:29:b4:40:38:fb:80:31:33:5c:62:67:62:dd:62:14:
36:fe:8f:8d:36:dc:0c:52:7b:0b:46:1c:58:94:2f:84:a9:54:
b0:a8:78:a0:9d:30:e9:0d:2f:a5:09:7d:3e:4e:75:16:56:f7:
94:a7:09:8f
Now removing private key:
rm example.key
and decoding the CSR again:
$ openssl req -noout -text -in example.csr
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:e2:23:3c:4e:d8:39:ce:9a:16:2f:e2:ef:e7:9b:
5d:7f:20:a7:9a:4b:dd:54:ad:6b:b3:ff:33:78:65:
f2:b1:e1:e3:b5:eb:23:9d:da:b3:8d:3c:2f:1f:60:
9a:17:36:df:0f:4e:3a:bd:fb:9f:73:d5:00:c2:65:
04:a2:77:e6:5b:27:f2:30:8f:57:31:c8:bf:d1:0a:
cc:db:f5:95:8e:98:ff:34:c5:ed:68:57:f8:43:47:
41:ff:cb:6d:27:ae:de:33:95:cd:d6:0a:f8:0b:25:
27:99:4e:6b:7d:d8:c4:dd:83:97:57:7a:42:69:4c:
41:e2:d6:7f:86:d0:6f:1b:c2:30:b2:e7:a9:ee:5b:
9d:a1:ce:80:ec:45:a6:ad:a4:6e:b1:6a:b1:68:ef:
c4:7d:5b:6c:e5:24:fe:54:f9:bb:09:48:5c:49:ca:
fe:41:28:bc:48:e8:02:bf:ac:b0:5b:c6:3f:bb:0e:
17:d4:31:02:31:27:b1:a3:7a:ff:82:49:f0:11:10:
64:53:44:ca:61:82:fd:3a:82:5c:07:48:23:1f:db:
e5:0f:64:79:09:19:25:b4:a5:07:42:d3:b4:54:75:
61:13:43:63:34:a2:72:55:07:d6:d1:8c:74:31:cb:
5c:54:1e:6a:e7:04:86:35:4c:d9:a4:31:3f:fd:36:
9c:59
Exponent: 65537 (0x10001)
Attributes:
a0:00
Signature Algorithm: sha256WithRSAEncryption
6d:fb:a6:e5:2b:89:5c:ef:5c:ca:cc:d3:9a:3d:b1:c1:41:9d:
b5:55:ca:2c:17:ca:ea:74:1d:79:b9:16:ec:81:08:95:94:98:
e1:2b:50:c7:46:eb:d4:97:09:25:cc:da:b4:bd:34:3c:5a:14:
c8:88:ed:21:99:63:e9:c0:0e:fa:bb:5d:a7:27:11:22:61:a1:
1f:d3:65:c8:cc:14:ff:d7:ce:19:29:14:67:ed:e5:b8:31:b5:
25:55:8e:59:42:f1:2a:6d:f9:fe:4a:be:08:b9:23:c5:b6:3b:
c8:7e:3f:0c:bd:bb:37:f6:fd:5a:0e:50:50:43:8e:59:f7:b6:
77:06:50:b2:45:2a:17:f4:53:5a:7c:3c:50:6d:de:74:e3:0e:
df:94:48:bc:a9:fa:b8:a1:9a:3e:dc:10:c8:50:cb:9b:a7:49:
cc:ac:88:66:54:e6:d3:06:81:95:f4:ac:e1:61:d7:88:18:74:
e8:8e:d2:8d:e9:71:7f:99:41:b9:b3:a1:ad:af:d6:0b:2f:46:
8d:fa:c4:29:b4:40:38:fb:80:31:33:5c:62:67:62:dd:62:14:
36:fe:8f:8d:36:dc:0c:52:7b:0b:46:1c:58:94:2f:84:a9:54:
b0:a8:78:a0:9d:30:e9:0d:2f:a5:09:7d:3e:4e:75:16:56:f7:
94:a7:09:8f
Conclusion: same results, proving the key is not needed.
Of course:
1) it was trivial to see that immediately, because if the key was needed when decoding the CSR, you would have need to specify it on command line of openssl (it does not poke out randomly at files)
2) it is of course silly to have deleted the private key because now if some certificate is indeed created out of this CSR, it is useless as the attached private key does not exist anymore.

Related

Is it possible to recover certificate thumbprint (sha1 fingerprint) from private key material?

Is it possible to recover certificate thumbprint (sha1 fingerprint) only from private key that will match original certificate thumbprint?
I can not find any information about how thumbprints are generated.
Private key material:
I have a .PFX file with single certificate and it's private key. From .PFX I export only private key:
openssl rsa -inform p12 -in cert.pfx -outform der -out cert.key.der
It is not possible to get a certificate fingerprint from the private key only. The private key matches only the public key in the certificate. There can actually be multiple certificates using the same public and private key, all having different certificate fingerprints. This is not uncommon - certificate renewals often use the same key pair as the previous (expired) certificate.
What would be possible is to get the public key fingerprint, but not the certificate fingerprint.

Self signed SSL certificate: Subject Alternative Name (SAN) gets lost when signing

I have two servers in my local network that should communicate with each other via https. I am very new to the topic of SSL certificates but I have found this little gist to be quite helpful: https://gist.github.com/fntlnz/cf14feb5a46b2eda428e000157447309
It asks me to first create a root CA that later signs my SSL certificates. But since I am working in my local network, the servers don't have a DNS. Just an IP address. This can be solved by appending a Subject Alternative Name to the certificate, which worked quite well for my signing request.
openssl req -in 192.168.178.83.csr -noout -text
returned:
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C = DE, ST = Brem, L = Brem, O = Self-signed certificate, CN = 192.168.178.83: Self-signed certificate
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:c0:5e:b7:ba:b2:1c:4d:21:9e:a9:d0:e8:3f:80:
b8:d7:0d:f7:d5:bc:bf:d7:e6:7a:47:84:c7:2b:1d:
7d:39:47:99:36:a0:19:10:81:d9:74:5a:91:fe:0b:
a3:90:fb:0d:4d:e1:d4:6d:52:4a:ec:8b:a3:4d:7a:
8c:2d:0a:96:84:54:ea:21:14:60:23:0a:18:58:27:
9a:ba:e1:7d:84:3f:62:58:1f:e6:77:19:02:9d:df:
ed:07:93:90:2f:f2:a8:0f:25:16:06:fb:b9:16:cb:
a8:20:06:25:4d:80:42:ce:5d:7a:77:d9:12:6f:00:
cb:04:bd:0a:32:ab:72:92:d9:8d:88:06:d7:75:e5:
d1:ef:07:f4:2f:8b:81:3f:60:8a:1a:fd:b4:fc:e8:
12:be:09:df:91:94:80:e3:e2:f7:9b:d5:f4:6d:51:
2c:b3:fa:97:76:33:17:a9:f0:0f:4d:10:b1:dc:26:
96:c0:b6:18:15:98:39:55:61:c9:ab:1b:d7:7e:ff:
ee:23:15:dd:92:eb:25:4e:38:b2:17:0e:53:38:ff:
23:25:52:ae:c8:76:04:81:0a:7c:59:e9:93:43:b3:
b3:a7:1f:46:4c:4a:ea:2b:9a:10:a5:94:8b:4e:09:
fc:a2:a5:1e:74:9c:57:1d:d5:47:6d:a0:03:b6:e4:
39:f1
Exponent: 65537 (0x10001)
Attributes:
Requested Extensions:
X509v3 Subject Alternative Name:
IP Address:192.168.178.83
Signature Algorithm: sha256WithRSAEncryption
59:ee:67:df:dc:21:0e:5a:eb:74:48:bd:e1:b2:4a:65:7e:12:
a4:42:77:0b:11:45:d7:f6:f5:f7:07:fa:a5:6c:0b:11:16:fa:
6f:41:0d:a3:4e:56:86:b6:c2:42:8d:b7:c2:50:94:1e:6f:61:
cf:48:8d:0f:4f:3a:85:18:00:da:7f:62:85:b3:2f:4f:23:25:
6e:eb:5f:83:32:a4:de:d1:5c:4e:fe:31:17:c6:1c:c5:4a:ed:
d9:ee:4a:13:bf:45:0c:d8:1c:64:59:51:4b:95:ec:62:63:58:
b6:d3:0a:b3:dd:1f:ea:d8:1d:0d:a7:45:6c:9e:a4:69:d7:f3:
69:ac:bb:62:14:84:8e:43:34:1f:7b:8f:2f:8d:01:67:8b:1e:
80:7e:35:59:b0:95:82:82:c6:f4:56:40:e3:b5:b8:63:c9:84:
0a:ab:ec:b7:ed:da:56:bc:e1:50:61:ad:8b:e5:52:9f:d0:5d:
dd:74:67:de:d3:b0:be:b3:1f:35:51:e8:6b:ac:d2:84:ef:a8:
35:dd:70:0e:32:f2:a1:1f:4a:be:39:a9:60:06:8a:3c:f0:05:
71:50:ed:85:41:31:f5:4c:df:71:8e:8e:22:08:ad:fd:55:89:
05:a4:53:44:d5:01:1f:d3:56:a2:b0:bc:7b:c9:e9:01:ea:ad:
3d:fb:95:52
But when I signed this according to the previously mentioned gist, openssl req -in mydomain.com.csr -noout -text returned:
Certificate:
Data:
Version: 1 (0x0)
Serial Number:
32:67:42:b9:db:c2:23:23:89:de:d1:5a:51:ff:6a:64:76:9e:89:36
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = DE, ST = Bremen, L = Bremen, O = Root-CA by Jere, OU = Kellerserver, CN = bla, emailAddress = blug#asdlfj.de
Validity
Not Before: Sep 21 17:16:12 2021 GMT
Not After : Feb 3 17:16:12 2023 GMT
Subject: C = DE, ST = Brem, L = Brem, O = Self-signed certificate, CN = 192.168.178.83: Self-signed certificate
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:c0:5e:b7:ba:b2:1c:4d:21:9e:a9:d0:e8:3f:80:
b8:d7:0d:f7:d5:bc:bf:d7:e6:7a:47:84:c7:2b:1d:
7d:39:47:99:36:a0:19:10:81:d9:74:5a:91:fe:0b:
a3:90:fb:0d:4d:e1:d4:6d:52:4a:ec:8b:a3:4d:7a:
8c:2d:0a:96:84:54:ea:21:14:60:23:0a:18:58:27:
9a:ba:e1:7d:84:3f:62:58:1f:e6:77:19:02:9d:df:
ed:07:93:90:2f:f2:a8:0f:25:16:06:fb:b9:16:cb:
a8:20:06:25:4d:80:42:ce:5d:7a:77:d9:12:6f:00:
cb:04:bd:0a:32:ab:72:92:d9:8d:88:06:d7:75:e5:
d1:ef:07:f4:2f:8b:81:3f:60:8a:1a:fd:b4:fc:e8:
12:be:09:df:91:94:80:e3:e2:f7:9b:d5:f4:6d:51:
2c:b3:fa:97:76:33:17:a9:f0:0f:4d:10:b1:dc:26:
96:c0:b6:18:15:98:39:55:61:c9:ab:1b:d7:7e:ff:
ee:23:15:dd:92:eb:25:4e:38:b2:17:0e:53:38:ff:
23:25:52:ae:c8:76:04:81:0a:7c:59:e9:93:43:b3:
b3:a7:1f:46:4c:4a:ea:2b:9a:10:a5:94:8b:4e:09:
fc:a2:a5:1e:74:9c:57:1d:d5:47:6d:a0:03:b6:e4:
39:f1
Exponent: 65537 (0x10001)
Signature Algorithm: sha256WithRSAEncryption
3b:2a:19:49:04:78:8f:bf:d9:39:d2:ca:16:64:38:40:0a:7b:
93:ef:07:1f:e8:ea:e6:b8:1b:7e:89:09:6c:75:e5:da:2a:0a:
79:41:26:5d:5d:e4:6f:e6:5a:87:66:65:39:a6:60:9a:31:92:
dc:c9:25:b3:5f:5d:cb:49:b0:be:c5:ad:d4:ec:89:f5:de:af:
42:ca:46:e2:1d:f3:52:b5:f9:b7:48:ff:89:92:8a:28:ad:98:
78:61:10:a8:f0:3b:ca:42:6d:7b:2c:47:3f:78:72:04:26:a6:
48:bd:b2:b3:ce:5d:e5:60:b5:0a:99:6f:6e:a5:17:87:f3:cd:
d3:ba:3e:de:87:f0:01:f6:0a:b2:a9:3c:d7:95:4b:b0:fd:80:
da:a3:5b:d3:7a:bd:d8:32:0e:7d:59:1a:d3:49:fd:cc:4b:e0:
03:17:40:32:8d:30:30:ef:37:da:ea:f0:19:88:a7:1a:2a:8f:
f7:c0:9a:34:53:8b:e7:9a:15:e0:5c:01:b4:0a:f1:a5:f2:7f:
8c:38:62:43:92:c7:39:a7:e3:0a:e6:f7:9a:2f:a9:60:8d:cc:
cc:e5:77:f9:ab:d9:03:52:64:15:11:b2:6f:d9:25:8b:50:1f:
48:ba:61:35:19:68:af:c2:37:ab:d1:d8:3d:ac:01:40:ab:37:
2d:12:b2:22:8c:dc:6a:c9:83:d4:d3:fb:47:e0:49:ca:f9:99:
14:ad:26:c5:54:68:fa:9c:94:d7:cd:a6:6b:01:f8:08:ee:5e:
b4:4e:ba:97:4a:19:07:13:2b:1b:3d:e0:e1:7f:6a:24:35:d8:
c1:46:a2:1a:15:a8:3c:86:8d:7e:f5:a1:6e:c9:72:f9:17:22:
8e:1f:13:a8:2f:ab:29:e4:7a:5d:a7:15:ef:58:fd:07:ec:d1:
47:58:7c:de:52:35:75:66:61:36:63:40:14:c0:6d:04:1b:2d:
c3:bb:18:97:df:ed:ed:f1:74:89:e0:b7:5f:63:f1:67:88:b5:
db:d4:04:e7:d9:ee:14:b3:71:bd:b8:25:a0:2b:87:f7:5c:d9:
58:3b:03:55:75:a4:53:33:99:66:a7:ab:ea:b7:f1:17:82:23:
6e:6c:df:95:fe:1d:16:2a:35:e0:96:7a:cd:9b:55:f7:da:f5:
a5:e0:55:26:16:58:29:80:e9:e0:a5:07:fd:e4:07:e1:d7:43:
ca:f6:7b:d7:53:ec:d6:d4:b2:b3:4e:75:8e:39:61:75:1a:75:
a0:d8:46:51:07:46:ca:7b:aa:44:b1:17:89:9d:64:21:61:a7:
c5:f0:18:eb:2c:61:61:7a:de:49:7d:c0:b0:6d:3f:89:c9:83:
5c:14:14:a8:0d:a8:8b:2f
My SAN extension seems to be missing there!
I am working on an Ubuntu machine.

Use of CA certificate in Certificate creation

I have read an article on how to create a local SSL certificate. The steps are basically as below:
1. create a key pair
openssl genrsa -des3 -out applicant.key 2048
2. create a certificate signing request
openssl req -new -sha256 -nodes -out applicant.csr -key applicant.key -config someCert.csr.cnf
3. create a cert for the applicant using the ca.key(private key) and cacert.pem (CA certificate)
openssl x509 -req -in applicant.csr -CA cacert.pem -CAkey ca.key -CAcreateserial -out applicant.crt -days 500 -sha256 -extfile localdomain.v3.ext
I got a few question regarding the steps.
a) When we create the key in step 1, is it a key pair or just private key?
b) When creating a certificate signing request in step 2, do we need a public key or private key?
c) When create a cert from CA, why do we need both ca private key and ca certificate? I believe the ca private key is used for digital signature, but what's the purpose of CA certificate?
When we create the key in step 1, is it a key pair or just private key?
applicant.key contains both the public and private elements. You can see them with openssl rsa -text -nout -in applicant.key, or in a more basic form with dumpasn1 or similar.
When creating a certificate signing request in step 2, do we need a public key or private key?
Both. You need the public key as that is going to be certified by the CA. You need the private key as you sign the CSR with this to provide Proof of Possession of the public key.
When create a cert from CA, why do we need both its private key and ca certificate?
Again, both. You need the private key in order to sign the certificate. You also need the CA certificate so that the CA can extract information used during the signing process from it.
As a minimum, this is the Subject field of the CA certificate which is used as the Issuer field of the signed certificate.
Another example is the AuthorityKeyIdentifier extension in the CA certificate, whose value is used as the SubjectKeyIdentfier extension in the applicant's certificate.
However, CAs are at liberty to use whatever they need. For example, Microsoft CAs will check the expiry date on the CA certificate and not issue an applicant a certificate that expires past this date (it truncates the validity of the certificate). In order to do that, it needs access to the CA certificate.

Misunderstanding CSR and X.509 functioning

After spending two days searching and finding answers to my questions only to realize these answers were only creating more questions and problems I couldn't solve, I resolved to ask for help here hoping I hadn't missed the information I'm looking for somewhere.
I've just began a project in which I have to exchange X.509 certificates with a client before starting to work with this client.
I've managed to understand well how and why X.509 certificate were made :
Make a CSR from a private key;
This CSR contains digital identity and a public key extracted from private key;
CSR is self-signed or sent to a CA who signs it with its own private key in order to validate the identity of the sender;
The CA sends back a certificate matching X.509 standard and proving you're not faking an identity and thus that the public key contained in X.509 is reliable.
So X.509 certificate is a way to exchange your public key with someone in order to counter a potential man-in-the-middle attack.
Using OpenSSL I've been able to simulate alone those operations in order to understand the functioning of these steps.
My first problem is that when I make a CSR from a private key (privateKey.pem) and then check if this private key matches the CSR, it doesn't.
I then self-sign the CSR with a different private key (signingPrivateKey.pem), check again if the X.509 certificate matches the private key, and it still does not (which seems normal because the CSR didn't either but both should match, shouldn't they ?).
Here are the OpenSSL commands :
#echo off
echo "Generates private key and puts it in SigningPrivateKey.pem"
echo.
openssl genrsa -out SigningPrivateKey.pem 1024
echo "Generates private key and puts it in privateKey.pem, then create CSR"
echo.
openssl req -newkey rsa:1024 -keyout privateKey.pem -out CSR_TEST.csr -nodes
echo "Checks if CSR and privateKey matches
echo.
openssl x509 -noout -modulus -in CSR_TEST.csr | openssl md5
openssl rsa -noout -modulus -in privateKey.pem | openssl md5
echo "Self sign CSR with private key"
echo.
openssl x509 -in CSR_TEST.csr -out CSR_TEST.pem -req -signkey
SigningPrivateKey.pem -days 1
echo. "Checks again if certificate and private key matches
openssl x509 -noout -modulus -in CSR_TEST.pem | openssl md5
openssl rsa -noout -modulus -in privateKey.pem | openssl md5
Here's the summarized input :
stdin = d41d8....8427e
stdin = f3213....4538c
Signature ok
stdin = 82baf...a0863
stdin = f3213...4538c
My second problem is the way to verify a X.509.
Let's say I manage to make a X.509 certificate from an input private key and the extracted public key matches with it. I send it to my client, who sends a certificate to.
How do we know this X.509 is reliable ? I've read somewhere that we need to "unsign" the X.509 certificate with the CA's public key, and compare the output with a hashed certificate, but everyone seems to say that an X.509 certificate is self-sufficient and that it proves by itself your identity. We'd just need to check its authenticity with an OpenSSL command ?
Please lighten me on this point.
Thanks for taking the time to read and understand my problems, once again I hope I'm not the only one facing those problems and that this post will help someone else.
Sorry for I'm not allowed yet to put more links in this post, otherwise I'd have been more accurate.
CSR/Key comparison
$ openssl req -in test.csr -modulus -noout | openssl md5
(stdin)= 76d44c1a05f535f5e78a648b41bdaf73
$ openssl rsa -in test.key -modulus -noout | openssl md5
(stdin)= 76d44c1a05f535f5e78a648b41bdaf73
You used openssl x509 on a CSR. They're not the same. And you clearly didn't look at the output before running it through MD5:
$ openssl x509 -in test.csr -modulus -noout
unable to load certificate
139958187611800:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:701:Expecting: TRUSTED CERTIFICATE
You haven't made it into a certificate yet, so the x509 command doesn't work.
Your after you do make the certificate and you check again, you're getting a different answer because you used -signkey. The documentation says that -signkey is used as a self-sign key, meaning it replaces the public key that was in the original request. If you use -signkey privateKey.pem your commands should show alignment.
Integrity
Each X.509 certificate contains the presented data (including the public key) and a signature. For "real" CAs there's usually a note (the Authority Information Access extension) which says how to find the CA's certificate. Whether you have it on-hand or you have to go retrieve it from the internet, the public key in the signing certificate can be used to validate that the data in the original certificate hasn't changed.
The signing CA itself had a certificate, so you can go another step and prove that it hasn't been altered.
Eventually you get to a root/self-signed certificate. Either you already have it and consider it trusted, or you don't, and you call the whole thing malarkey.
The only thing that can really be verified about a self-signed certificate which isn't part of your inbuilt trust store is that it wasn't modified after it was created. The only security benefit of this is repudiation: If someone edited a certificate you created and added an extension which says something to the effect of "Your mother is a smelly donkey salesman!" you can demonstrate that the self-signed signature is invalid.
$ openssl x509 -in test.cer -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 11195357966677484939 (0x9b5de6c15126a58b)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, OU=.NET Framework (CoreFX), CN=localhost
Validity
Not Before: Mar 2 01:48:00 2016 GMT
Not After : Mar 2 01:48:00 2017 GMT
Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, OU=.NET Framework (CoreFX), CN=localhost
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:af:81:c1:cb:d8:20:3f:62:4a:53:9e:d6:60:81:
75:37:23:93:a2:83:7d:48:90:e4:8a:19:de:d3:69:
73:11:56:20:96:8d:6b:e0:d3:da:a3:8a:a7:77:be:
02:ee:0b:6b:93:b7:24:e8:dc:c1:2b:63:2b:4f:a8:
0b:bc:92:5b:ce:62:4f:4c:a7:cc:60:63:06:b3:94:
03:e2:8c:93:2d:24:dd:54:6f:fe:4e:f6:a3:7f:10:
77:0b:22:15:ea:8c:bb:5b:f4:27:e8:c4:d8:9b:79:
eb:33:83:75:10:0c:5f:83:e5:5d:e9:b4:46:6d:df:
be:ee:42:53:9a:ef:33:ef:18:7b:77:60:c3:b1:a1:
b2:10:3c:2d:81:44:56:4a:0c:10:39:a0:9c:85:cf:
6b:59:74:eb:51:6f:c8:d6:62:3c:94:ae:3a:5a:0b:
b3:b4:c7:92:95:7d:43:23:91:56:6c:f3:e2:a5:2a:
fb:0c:14:2b:9e:06:81:b8:97:26:71:af:2b:82:dd:
39:0a:39:b9:39:cf:71:95:68:68:7e:49:90:a6:30:
50:ca:77:68:dc:d6:b3:78:84:2f:18:fd:b1:f6:d9:
ff:09:6b:af:7b:eb:98:dc:f9:30:d6:6f:cf:d5:03:
f5:8d:41:bf:f4:62:12:e2:4e:3a:fc:45:ea:42:bd:
88:47
Exponent: 8589935681 (0x200000441)
X509v3 extensions:
X509v3 Subject Key Identifier:
78:A5:C7:5D:51:66:73:31:D5:A9:69:24:11:4C:9B:5F:A0:0D:7B:CB
X509v3 Authority Key Identifier:
keyid:78:A5:C7:5D:51:66:73:31:D5:A9:69:24:11:4C:9B:5F:A0:0D:7B:CB
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: sha256WithRSAEncryption
77:75:6d:05:ff:a6:ad:fe:d5:b6:d4:af:b5:40:84:0c:6d:01:
cf:6b:3f:a6:c9:73:df:d6:1f:ca:a0:a8:14:fa:1e:24:69:01:
9d:94:b1:d8:56:d0:7d:d2:b9:5b:85:50:df:d2:08:59:53:a4:
94:b9:9e:fc:ba:a7:98:2c:e7:71:98:4f:9d:4a:44:5f:fe:e0:
62:e8:a0:49:73:6a:39:fd:99:4e:1f:da:0a:5d:c2:b5:b0:e5:
7a:0b:10:c4:1b:c7:fe:6a:40:b2:4f:85:97:73:02:59:3e:60:
b9:8d:d4:81:1d:47:d9:48:ed:f8:d6:e6:b5:af:80:a1:82:74:
96:e2:0b:fd:24:0e:46:76:74:50:4d:4e:47:03:33:1d:64:70:
5c:36:fb:6e:14:ba:bf:d9:cb:ee:c4:4b:33:a8:d7:b3:64:79:
90:0f:3c:5b:ba:b6:9c:5e:45:3d:18:07:83:e2:50:80:51:b9:
98:c0:38:e4:62:25:71:d2:ab:89:1d:89:8e:54:58:82:8c:f1:
86:79:51:7d:28:db:ca:bf:72:e8:13:07:bf:d7:21:b7:3d:db:
17:51:12:3f:99:d8:fc:0d:53:37:98:c4:db:d1:47:19:d5:d8:
a8:5b:00:a1:44:a3:67:67:7b:48:89:1a:9b:56:f0:45:33:48:
11:ba:cb:7a
And
$ openssl x509 -in alsotest.cer -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 11195357966677484939 (0x9b5de6c15126a58b)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, OU=.NET Framework (CoreFX), CN=localhost
Validity
Not Before: Mar 2 01:48:00 2016 GMT
Not After : Mar 2 01:48:00 2019 GMT
Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, OU=.NET Framework (CoreFX), CN=localhost
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:af:81:c1:cb:d8:20:3f:62:4a:53:9e:d6:60:81:
75:37:23:93:a2:83:7d:48:90:e4:8a:19:de:d3:69:
73:11:56:20:96:8d:6b:e0:d3:da:a3:8a:a7:77:be:
02:ee:0b:6b:93:b7:24:e8:dc:c1:2b:63:2b:4f:a8:
0b:bc:92:5b:ce:62:4f:4c:a7:cc:60:63:06:b3:94:
03:e2:8c:93:2d:24:dd:54:6f:fe:4e:f6:a3:7f:10:
77:0b:22:15:ea:8c:bb:5b:f4:27:e8:c4:d8:9b:79:
eb:33:83:75:10:0c:5f:83:e5:5d:e9:b4:46:6d:df:
be:ee:42:53:9a:ef:33:ef:18:7b:77:60:c3:b1:a1:
b2:10:3c:2d:81:44:56:4a:0c:10:39:a0:9c:85:cf:
6b:59:74:eb:51:6f:c8:d6:62:3c:94:ae:3a:5a:0b:
b3:b4:c7:92:95:7d:43:23:91:56:6c:f3:e2:a5:2a:
fb:0c:14:2b:9e:06:81:b8:97:26:71:af:2b:82:dd:
39:0a:39:b9:39:cf:71:95:68:68:7e:49:90:a6:30:
50:ca:77:68:dc:d6:b3:78:84:2f:18:fd:b1:f6:d9:
ff:09:6b:af:7b:eb:98:dc:f9:30:d6:6f:cf:d5:03:
f5:8d:41:bf:f4:62:12:e2:4e:3a:fc:45:ea:42:bd:
88:47
Exponent: 8589935681 (0x200000441)
X509v3 extensions:
X509v3 Subject Key Identifier:
78:A5:C7:5D:51:66:73:31:D5:A9:69:24:11:4C:9B:5F:A0:0D:7B:CB
X509v3 Authority Key Identifier:
keyid:78:A5:C7:5D:51:66:73:31:D5:A9:69:24:11:4C:9B:5F:A0:0D:7B:CB
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: sha256WithRSAEncryption
77:75:6d:05:ff:a6:ad:fe:d5:b6:d4:af:b5:40:84:0c:6d:01:
cf:6b:3f:a6:c9:73:df:d6:1f:ca:a0:a8:14:fa:1e:24:69:01:
9d:94:b1:d8:56:d0:7d:d2:b9:5b:85:50:df:d2:08:59:53:a4:
94:b9:9e:fc:ba:a7:98:2c:e7:71:98:4f:9d:4a:44:5f:fe:e0:
62:e8:a0:49:73:6a:39:fd:99:4e:1f:da:0a:5d:c2:b5:b0:e5:
7a:0b:10:c4:1b:c7:fe:6a:40:b2:4f:85:97:73:02:59:3e:60:
b9:8d:d4:81:1d:47:d9:48:ed:f8:d6:e6:b5:af:80:a1:82:74:
96:e2:0b:fd:24:0e:46:76:74:50:4d:4e:47:03:33:1d:64:70:
5c:36:fb:6e:14:ba:bf:d9:cb:ee:c4:4b:33:a8:d7:b3:64:79:
90:0f:3c:5b:ba:b6:9c:5e:45:3d:18:07:83:e2:50:80:51:b9:
98:c0:38:e4:62:25:71:d2:ab:89:1d:89:8e:54:58:82:8c:f1:
86:79:51:7d:28:db:ca:bf:72:e8:13:07:bf:d7:21:b7:3d:db:
17:51:12:3f:99:d8:fc:0d:53:37:98:c4:db:d1:47:19:d5:d8:
a8:5b:00:a1:44:a3:67:67:7b:48:89:1a:9b:56:f0:45:33:48:
11:ba:cb:7a
To spare you the eye strain: One of them has an expiration in the current past, another has an expiration date in the current future. (I was too lazy to inject an extension).
Which one is correct?
$ openssl verify test.cer
test.cer: C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, OU = .NET Framework (CoreFX), CN = localhost
error 18 at 0 depth lookup:self signed certificate
C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, OU = .NET Framework (CoreFX), CN = localhost
error 10 at 0 depth lookup:certificate has expired
OK
$ openssl verify alsotest.cer
alsotest.cer: C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, OU = .NET Framework (CoreFX), CN = localhost
error 18 at 0 depth lookup:self signed certificate
OK
Drat, they're both correct. Or are they? Wait, openssl verify doesn't check self-signed signatures normally, because it usually doesn't matter.
$ openssl verify -check_ss_sig test.cer
test.cer: C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, OU = .NET Framework (CoreFX), CN = localhost
error 18 at 0 depth lookup:self signed certificate
C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, OU = .NET Framework (CoreFX), CN = localhost
error 10 at 0 depth lookup:certificate has expired
OK
$ openssl verify -check_ss_sig alsotest.cer
alsotest.cer: C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, OU = .NET Framework (CoreFX), CN = localhost
error 18 at 0 depth lookup:self signed certificate
C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, OU = .NET Framework (CoreFX), CN = localhost
error 7 at 0 depth lookup:certificate signature failure
140450704717464:error:04091068:rsa routines:INT_RSA_VERIFY:bad signature:rsa_sign.c:278:
140450704717464:error:0D0C5006:asn1 encoding routines:ASN1_item_verify:EVP lib:a_verify.c:218:
There we go. alsotest.cer was modified (without being resigned) to extend its expiration date.

verifying a file signature with openssl dgst

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