Reputation: 566
I implemented an example (for better understanding for myself) of how digital signatures work (in my case with php).
I used the story from Bob and Alice under "How is a digital signature used for authentication?" from http://www.verisign.com.au/repository/tutorial/digital/intro1.shtml
"Suppose Alice wants to send a signed message to Bob. She creates a message digest by using a hash function on the message. The message digest serves as a "digital fingerprint" of the message; if any part of the message is modified, the hash function returns a different result. Alice then encrypts the message digest with her private key. This encrypted message digest is the digital signature for the message. Alice sends both the message and the digital signature to Bob. When Bob receives them, he decrypts the signature using Alice's public key, thus revealing the message digest. To verify the message, he then hashes the message with the same hash function Alice used and compares the result to the message digest he received from Alice. If they are exactly equal, Bob can be confident that the message did indeed come from Alice and has not changed since she signed it. If the message digests are not equal, the message either originated elsewhere or was altered after it was signed (or the private key is different)."
Before I post the code I would like to mention that this is probably not the right way not using standard generated key. But I should give me (and maybe you) an understanding of how signatures work.
echo "Example 2 <br><br>";
$res = openssl_pkey_new();
/* Extract the private key from $res to $privKey */
openssl_pkey_export($res, $privKey);
/* Extract the public key from $res to $pubKey */
$pubKey = openssl_pkey_get_details($res);
$pubKey = $pubKey["key"];
$message = "Im a message";
echo "<br><br><strong>Public key:</strong><br>";
echo $pubKey;
echo "<br><br><strong>Private key:</strong><br>";
echo $privKey;
echo "<br><br><strong>Message:</strong><br>";
echo $message;
echo "<br><br><strong>Message digest:</strong><br>";
echo $md5message = sha1($message);
echo "<br><br><strong>Message digest encrypted(signature):</strong><br>";
openssl_private_encrypt($md5message, $crypted, $privKey);
echo $crypted;
echo "<br><br><strong>Bob uses sha1 as well for the message:</strong><br>";
echo $md5message = md5($message);
echo "<br><br><strong>Bob checks with decrypt(verify):</strong><br>";
openssl_public_decrypt($crypted, $decrypted, $pubKey);
echo $decrypted;
I have 3 questions:
1) Is the workflow right on how signatures work? What should I change (as mentioned before I dont want to generate "proper".pem,.crt etc keys...would be next step for me).
2) In my understanding the private key was always to decrypt. The public key for encryption. I am aware wording here is sign for the private key, and verify with the public key. Obviously I can verify it in this example with only the public key. I cant get my head around that. How is this possible? Maybe you can give me a better example or links?
3) What should I change in my implementation?
Thanks in advance.
Upvotes: 0
Views: 1573
Reputation: 93978
OK, I'll give some remarks.
The text about Alice and Bob seems correct, although the last sentence "If the message digests are not equal, the message either originated elsewhere or was altered after it was signed." obviously can be extended with "or the message signed with a different private key".
The workflow is about correct, although openssl_private_encrypt
is a bit too high level to show what is really happening. It is likely to perform padding for signature generation, but without encoding the OID of the hash algorithm used (see the rather readable PKCS#1 specifications to see what I'm talking about). So in that sense your signature scheme is unlikely to verify with anything else out there.
So obviously the verify part is missing the actual verification, you need to compare the resulting hash with one you calculate locally. Furthermore you should never ever use MD5. Possibly you should use the PSS padding scheme instead of the older PKCS#1 v1.5 compatible scheme.
Upvotes: 1