Web Security: Digital Signatures

In the previous posts, you saw how hashing algorithms and cryptography helps to security a communication, regarding confidentiality and integrity. However, they just were pieces of the puzzle, applying them alone, was not enough.

Those posts left an unanswered question:

How does the destination (Mary) know if a message and its hashing was modified after the origin (John) deliveries it?

Cryptography and hashing, together, answer this question, creating a digital signature.

TRY IT YOURSELF: You can find the source code of this post here.

Web Security Series

The Problem

In the previous posts, you faced an attacker who was not authenticated and authorized, but, still, he changed the message content, as follows in John and Mary relationship example:

Toxic ex-boyfriend captures the message and change it

First, Mary authenticates John well, so, she accepted the Love you message. Second, John asks if he can meet her parents, however, the toxic ex-boyfriend captures the message and changes it to Hate you. As Mary already authenticated John, she thinks the second message is from him, so, she accepts it.

This scenario gave you two problems:

  • The original message was modified and Mary doesn’t realize it.
  • Mary authenticates John, however, that authentication is weak and the Toxic Ex-boyfriend was able to send messages to Mary.

Joining hashing algorithms with asymmetric cryptography, solves this problem.

What is a Digital Signature?

A Digital Signature is a way to verify that a message sent by a party:

  • Was not modified in transit. The message arrives exactly as it was sent, or the destination realizes the message was modified, and it is rejected.
  • Was sent by who the message says. As destination, you are sure that who send the message, is who you are expecting, and not a third party.

To accomplish this, a Digital Signature uses:

  • A hashing algorithm to create a unique hash that represent the message, so, the destination can check if the message was modified in transit.
  • A asymmetric cryptography algorithm, so, the origin encrypts the hash, to send to the destination.

John and Mary Communication With Signatures

Let’s use John and Mary relationship to express the Digital Signature process. First, John needs to sign the message he wants to send.

John signs the Love you message

First, John generates public and private keys to use asymmetric cryptography. Next, John creates the hash of the message he wants to send and encrypt it (sign it) with his private key. And finally, John creates a message with the plain “Love you” text plus the encrypted hash (the signature).

As the hash is encrypted, it cannot be changed, besides, only the parties with the public key, will be able to read it.

Now, John sends the message to Mary:

John sends the message and the signature to Mary

The message contains the signature. Now, Mary needs to process the message and verify if was sent by John, and if was not modified in transit:

Mary reads the message and verify the hashs

First, Mary decrypts the signature using John’s public key, getting the “Love you” hash inside. If she fails to decrypt the signature, that means, the message is not from John, so, she rejects it. As she is using John’s public key, if she succeeds decrypting the message, she knows that the message was sent by John, using his private key.

NOTE: Remember, the public and private keys are peer, they make sense and work together.

Finally, Mary applies the same hashing algorithm used by John to the plain “Love you” message, and the result is compared with the signed hash. If both are equal, she knows the message was not altered in transit, if the hashes are different, she knows that the message was modified, and she rejected it.

Toxic Ex boyfriend in the Middle

Now, let’s see what the Toxic Ex Boyfriend can do using signatures:

The Toxic Ex Boyfriend captures the message and change it

The Toxic Ex Boyfriend captures the message, and he is able to read it, as it is in plain text. Besides, he can change it. Also, if he has access to John’s public key, he is able to read the signature, but, he cannot change it, as the signature was created with John’s private key.

Mary reacts to this message as follows:

Mary verifies the Ex Boyfriend message and rejects it

First, Mary decrypts the signature using John’s public key, getting the “Love you” hash inside and applies the same hashing algorithm used by John to the plain “Hate you” message, sent by the Ex Boyfriend, and the result is compared with the signed hash. As both hashes are different, Mary realizes the message was altered on transit, and she rejects it.

The Toxic Ex Boyfriend might try to send a message to Mary using his own private key, but, when Mary tries to decrypt it, using John’s public key, will fail. That means, John didn’t send that message.

Did We solve the Open Questions?

Let’s check the open questions we have until now:

How does the destination (Mary) know if a message and its hashing was modified after the origin (John) deliveries it?

We use digital signatures, putting together hashing and asymmetric algorithms.

How does John share the key with Mary in a safe manner?

In this post, John’s key arrives to Mary magically, we don’t know yet how to do this safely

How can Mary and John communicate securely in a two way fashion?

Again, in this post, we showed how John communicates with Mary, but not the other way around.

Java Example: Digital Signatures

The following code shows an example of digital signatures in Java:

public class SignaturesExample {
  private PrivateKey privateKey;
  private PublicKey publicKey;

  @Before
  public void before()
          throws NoSuchAlgorithmException {
    KeyPairGenerator keyGen = KeyPairGenerator
            .getInstance("RSA");
    keyGen.initialize(2048);

    KeyPair pair = keyGen.generateKeyPair();

    privateKey = pair.getPrivate();
    publicKey = pair.getPublic();
  }

  @Test
  public void signAndVerify()
          throws SignatureException,
          NoSuchAlgorithmException,
          InvalidKeyException {

    Signature sign = Signature
            .getInstance("SHA256withRSA");
    sign.initSign(privateKey);

    byte[] originalMessage = "love you".getBytes();
    sign.update(originalMessage);

    byte[] digitalSignature = sign.sign();

    Signature signVerifier = Signature
            .getInstance("SHA256withRSA");
    signVerifier.initVerify(publicKey);

    byte[] currentMessage = "love you".getBytes();

    signVerifier.update(currentMessage);

    boolean isCorrect = signVerifier
            .verify(digitalSignature);

    assertThat(isCorrect).isTrue();
  }

  @Test
  public void signAndVerifyError()
          throws SignatureException,
          NoSuchAlgorithmException,
          InvalidKeyException {

    Signature sign = Signature
            .getInstance("SHA256withRSA");
    sign.initSign(privateKey);

    byte[] originalMessage = "love you".getBytes();
    sign.update(originalMessage);

    byte[] digitalSignature = sign.sign();

    Signature signVerifier = Signature
            .getInstance("SHA256withRSA");
    signVerifier.initVerify(publicKey);

    byte[] currentMessage = "hate you".getBytes();

    signVerifier.update(currentMessage);

    boolean isCorrect = signVerifier
            .verify(digitalSignature);

    assertThat(isCorrect).isFalse();
  }
}

In the first test case, we created a pair keys, public and private, and sign the message “love you” with the Signature class using the private key. After we sign, we verify the signature, sending the same “love you” message, the public key and the previous generated signature.

In the second test case, we do exactly the same, but, we verify against a different message, “hate you”, resulting in a invalid signature.

Final Though

We are getting closed to a better way to communicate between two parties, in a secure manner.

Hashing and cryptography together create a digital signature, used to validate who send the message, and verify the integrity of it.

Still, we have a lot of unanswered questions, but, we are moving forward each time.

In the next post you will see the answer to the following question:

How does John share the key with Mary in a safe manner?

How can Mary and John communicate securely in a two way fashion?

Digital certificates and SSL/HTTPs help us.

If you liked this post and are interested in hearing more about my journey as a Software Engineer, you can follow me on Twitter and travel together.

6 comments

Leave a comment