The labs on this site need JavaScript to run. The same content is written out below.
Learn › Security › Cryptography
Hashing, encryption, and signatures
What hides, what checks, and what cannot be undone
Hash functions, symmetric-key cryptography, public-key cryptography, and signatures come up all the time in security, and each does a different job. Try each of the five tools on the message "Order 100 won", then change the content or use a different key and see what happens. All values on screen were actually computed.
Checked against real execution · Actually computed and verified with the cryptography library of Node.js
Concepts in this lab
- Hash function and salt
- A hash function turns an input into a fixed-length value, and the original input cannot be recovered from the result. For passwords, the hash value is stored instead of the plain text, so the plain text is not exposed even if the data leaks. A salt is a random value that is added to each password and is different for each one. It makes the same password produce a different hash, which blocks attacks that use precomputed lists of hashes.
- Symmetric-key cryptography and public-key cryptography
- Symmetric-key cryptography uses the same key to encrypt and to decrypt. It is fast, but it has the problem that the key must be shared safely with the other party (AES). Public-key cryptography uses a pair of keys, a public key and a private key. Data encrypted with the public key can be decrypted only with the private key, so there is no key-sharing problem, but it is slow (RSA). In practice, public-key cryptography is used to exchange a symmetric key safely, and then the symmetric key encrypts the data.
- HMAC and digital signatures
- Techniques for confirming that a message was not changed on the way and that the legitimate party sent it. HMAC hashes the message together with a secret key that both sides share to produce an authentication code. With a digital signature, the sender signs with a private key and the receiver verifies with the public key. Only the signer can create the signature, so the sender cannot deny having sent the message.
- JSON Web Token (JWT)
- A token that carries content such as user information (claims) and has a signature attached. It has three parts: a header, a payload, and a signature. The server verifies the signature to confirm that the token was not forged, and it does not need to look up a separate store. The payload is encoded, not encrypted, so anyone can read its contents. Do not put sensitive information in it.
Try these
- Default settings — A hash. The same input always gives the same value, and the value cannot be reversed.
- Hash: change just one character — The result becomes a completely different value.
- Symmetric key: decrypt with a different key — Without the same key, you cannot decrypt.
- Public key: decrypt with the public key — The key that locked it cannot open it. Only the matching private key opens it.
- HMAC: change the content — The signature no longer matches, so the tampering is revealed. JWT works this way.
- Digital signature: sign with someone else's key — Verifying with the public key reveals that it is fake.
Running with the default settings
- The message to send is "Order 100 won".
- Put into a hash function, the message gives a value of a fixed length. No key is used. If you put in the same message again, anyone, at any time, gets exactly the same value.
- There is no calculation that reverses "Order 100 won" from this value by a formula (however, if you hash candidates and compare, a short input can be found). A hash goes in one direction only. That is why it is used to store things such as passwords, which do not need to be known in their original form, but for passwords you use a dedicated salted hash.
Result of this run
- Hash: it cannot be reversed, it has no key, and the same input always gives the same value. Use it to compare whether contents are the same, or to store a value without keeping the original as it is.
Code
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest(message.getBytes(UTF_8));
// There is no key. Anyone gets the same value from the same input.
Assumptions of this model
The hash, ciphertext, and signature values on screen, and the success and failure results, were all actually computed and verified with the cryptography library of Node.js (SHA-256, AES-256-GCM, RSA with a 2048-bit key, HMAC-SHA256). The RSA values are long, so only the first part is shown, and the values differ every time the keys are created. In a real service, you do not implement these yourself; you use proven libraries and protocols (TLS, a JWT library). The values in this English edition were computed again in the same way for the English message text, so they differ from the values in the Korean edition.
Previous lab: Dependencies and the supply chain · Next lab: TLS handshake