Hashing is the process of converting a given value into another value. A hash function is used to generate the new value according to a mathematical algorithm. The result of a hash function is known as a hash value or, simply, a hash.
Good hash functions generally use a one-way hashing algorithm: in other words, the hash cannot be converted back into the original value.
What a hash function produces
A hash function takes as input a piece of data of any size — a word, a password, a file several gigabytes long — and produces as output a bit string of fixed length. This output has several names depending on the document: hash, fingerprint, condensate, or digest in English. Its length depends on the algorithm chosen, never on the size of the input.
SHA-256 (Secure Hash Algorithm, the variant producing 256 bits) always produces 256 bits, that is 32 bytes. These 32 bytes are almost always displayed in hexadecimal, a notation that represents each byte by two characters taken from 0 to 9 and a to f. A SHA-256 fingerprint therefore appears as a string of 64 characters.
$ printf 'bonjour' | sha256sum
2cb4b1431b84ec15d35ed83bb927e27e8967d75f4bcd9cc4b25c8d879ae23e18 -
$ printf 'Bonjour' | sha256sum
9172e8eec99f144f72eca9a568759580edadb2cfd154857f07e657569493bc44 -
These two commands reproduce as they are on any Linux system that has the sha256sum command, which is the case for the common distributions. The printf command is used rather than echo because it does not add a line break: this extra character would be part of the hashed data and would entirely change the result. The dash at the end of the output indicates that the data came from standard input and not from a file.
Two observations fit in this example. The first: the same input will give the same output indefinitely, on this machine as on another. The second: the change from a lowercase to an uppercase letter, that is a single bit of difference in the first byte, produces a fingerprint with no visible relation to the previous one.
The four properties expected of a cryptographic hash function
Not every function that reduces a piece of data to a short value is cryptographic. A CRC32 (Cyclic Redundancy Check on 32 bits) detects a transmission error very well, but deliberately building two files with the same CRC32 is within the reach of a laptop. The qualifier “cryptographic” presupposes four properties.
Determinism
The same input always produces the same fingerprint. This is what makes it possible to compare two fingerprints to conclude that two pieces of data are identical. Be careful about what is really being hashed: these are bytes, not a meaning. An accented text encoded in UTF-8 and the same text encoded in ISO-8859-1 give two different fingerprints; a text file saved with Windows line endings (carriage return then line feed) differs from the same file with Unix line endings. A fingerprint that does not match is very often explained this way.
Preimage resistance
Given a fingerprint, it must be infeasible to find a piece of data that produces it. This is the property that the introduction calls the one-way character. There is no inverse operation: the only known way is to try inputs until the fingerprint is found again, which represents on the order of 2256 attempts for SHA-256.
This guarantee has a limit that beginners underestimate: it applies to the function, not to the data. If the input belongs to a small or predictable set — a date of birth, a phone number, an email address, a common password — the attacker does not need to break anything. They enumerate the candidates, hash them, and compare. Hashing a guessable piece of data does not protect it.
A variant of this property is second-preimage resistance: starting from a known piece of data, it must be infeasible to build another, different one that produces the same fingerprint.
Collision resistance
A collision is a pair of two different inputs having the same fingerprint. Collisions necessarily exist: the possible inputs are unlimited in number, the outputs are finite in number. The property therefore does not require that none exist, but that no one knows how to build one.
The cost of finding a collision is markedly lower than that of a preimage, because of what is called the birthday paradox: for a fingerprint of n bits, on the order of 2n/2 attempts are needed. For SHA-256, the real security against collisions is therefore on the order of 2128, and not 2256. It is this bound, half as large, that explains why the too-short fingerprints were abandoned.
The avalanche effect
Changing a single bit of the input must change about half of the bits of the output, with no exploitable regularity. The example of bonjour and Bonjour above shows it. The practical consequence is important: nothing can be deduced from the resemblance between two fingerprints. Two nearly identical files have completely dissimilar fingerprints. Comparing fingerprints is an all-or-nothing answer, never a measure of closeness.
Hashing, encryption, encoding: three distinct operations
This is the most frequent confusion at the start of learning, and it has real consequences on the security of an application. The three operations transform a piece of data into another string of characters, but they do not serve the same purpose and do not offer the same guarantees.
- Encoding changes the representation of a piece of data. It is reversible by anyone, without a secret, and that is its purpose. Base64, for example, represents arbitrary bytes using 64 printable characters, in order to pass them through an email or a JSON document. Encoding provides no confidentiality.
- Encryption makes a piece of data unreadable for anyone who does not hold the key, and perfectly readable for anyone who does. It is reversible in both directions, by design. AES (Advanced Encryption Standard) and ChaCha20 are encryption algorithms.
- Hashing is not reversible by anyone, not even by the one who computed the fingerprint. There is no key and no decryption. The output has a fixed size, independent of the input.
$ printf 'bonjour' | base64
Ym9uam91cg==
$ echo 'Ym9uam91cg==' | base64 -d
bonjour
Two common phrasings are therefore to be set aside. “Encrypted password” describes nothing usable: if a password can be recovered, it means it was encrypted and that the key is stored somewhere, which brings the problem back to storing the key. And a password encoded in Base64 is a cleartext password, simply less readable to the eye.
Computing a fingerprint under Linux and under Windows
Under Linux
$ printf 'bonjour\n' > exemple.txt
$ sha256sum exemple.txt
9cec0af545144159bac85c7b908d5e0b9b0ef961497401c5ad8da26f065ad926 exemple.txt
$ md5sum exemple.txt
94baaad4d1347ec6e15ae35c88ee8bc8 exemple.txt
$ openssl dgst -sha256 exemple.txt
SHA2-256(exemple.txt)= 9cec0af545144159bac85c7b908d5e0b9b0ef961497401c5ad8da26f065ad926
The GNU coreutils package, present on nearly all distributions — systems built on BusyBox, such as Alpine, provide only a restricted equivalent of it —, provides sha256sum, sha512sum, sha1sum, md5sum and b2sum. The openssl dgst command covers more algorithms, for example openssl dgst -sha3-256. The label it prints depends on the installed version: recent versions write SHA2-256(...) where older ones wrote SHA256(...). The list of algorithms actually available on the machine is obtained with openssl dgst -list.
Under Windows
PS> Get-FileHash .\exemple.txt
Algorithm Hash Path
--------- ---- ----
SHA256 9CEC0AF545144159BAC85C7B908D5E0B9B0EF961497401C5AD8DA26F065AD926 C:\...\exemple.txt
PS> Get-FileHash .\exemple.txt -Algorithm MD5
The PowerShell command Get-FileHash uses SHA-256 by default; the -Algorithm parameter accepts in particular SHA1, SHA256, SHA384, SHA512 and MD5. Its output is in uppercase whereas sha256sum writes in lowercase: it is the same value, the comparison simply has to ignore case. A classic command-line variant also exists with certutil -hashfile exemple.txt SHA256.
A methodological note: comparing 64 hexadecimal characters by eye, or by looking only at the beginning and the end, does not constitute a verification. The comparison must be done by the machine, as in the following section.
What hashing really serves
Verifying a download
Publishers put alongside their files a fingerprint file, often named SHA256SUMS, containing one line per file. The sha256sum command knows how to read this format again and do the comparison itself, with the -c option.
$ sha256sum exemple.txt > SHA256SUMS
$ sha256sum -c SHA256SUMS
exemple.txt: Réussi
The word displayed depends on the language of the system: a system configured in English prints OK. In case of a difference, the command reports the failure and returns a non-zero return code, which makes it possible to use it in a script.
The scope of this verification deserves to be understood. It proves that the file received is indeed the one whose fingerprint was published. It therefore protects against accidental corruption: interrupted transfer, faulty mirror, damaged media. Against an adversary who controls the server, it is not enough: the one who can replace the file can generally also replace the page that displays the fingerprint. This is why serious projects publish an electronic signature of the fingerprint file, verifiable with a public key obtained through another channel.
Identifying a file by its content
A fingerprint constitutes a content identifier: since no collision is known for SHA-256, one concludes in practice that two files with different names having the same SHA-256 fingerprint have the same content. This property is used by the Git version manager, which names its internal objects by their fingerprint, by backup systems that avoid storing an identical block twice, and by malware fingerprint databases.
Signing a document
An electronic signature does not apply to the document itself but to its fingerprint: the latter is short, of fixed size, and quick to compute, whereas signing operations are costly. This construction explains why collision resistance is not a theoretical concern: if an attacker knows how to build two documents with the same fingerprint, they have the first one signed and present the second one with the same valid signature.
Authenticating a message
An HMAC (keyed-Hash Message Authentication Code) combines a hash function and a secret key to produce a value that proves both the integrity of the message and knowledge of the key. This construction must not be improvised by simply concatenating the key and the message: SHA-256 and SHA-512, built on the so-called Merkle-Damgård scheme, are subject to length extension (the truncated variants of the same family, such as SHA-384, escape it), which allows a third party to lengthen the message and recompute a valid fingerprint without knowing the key. HMAC is designed precisely to prevent this. SHA-3 and BLAKE2 do not present this weakness.
The state of the algorithms in practice
MD5 (Message-Digest Algorithm 5, 128 bits) is broken for collision resistance: the fabrication of two inputs with the same fingerprint was demonstrated in 2004 and is now computed in a few seconds on an ordinary machine. MD5 must no longer be used as soon as an adversary can influence the hashed content: signature, integrity check of an update, file identification in a security context.
SHA-1 (160 bits) has followed the same path: a full collision was published in 2017 under the name SHAttered, in the form of two different PDF files with the same fingerprint, then a chosen-prefix collision in 2020, even closer to real spoofing scenarios. SHA-1 has been removed from the certificates of the public certification authorities and prohibited for new signatures; it still remains in old systems.
One clarification that avoids a misunderstanding: in both cases, it is collision resistance that fell, not preimage resistance. Recovering a piece of data from an MD5 fingerprint remains out of reach by direct computation — which does not prevent recovering it by enumeration when the data is guessable, as explained above. This nuance does not excuse the use of MD5; it simply explains what is broken and what is not.
Three families are used with no published reservation to date (state of the known work at the time of writing, in 2026). SHA-2 groups together in particular SHA-224, SHA-256, SHA-384 and SHA-512, no collision is known in it and SHA-256 constitutes the reasonable default choice for integrity. SHA-3, derived from the Keccak algorithm and standardized in 2015, relies on a different construction, called a sponge; it is not intended to replace SHA-2 but to offer a fallback that would not share its possible weaknesses. BLAKE2 and BLAKE3 are fast in software and are found above all in backup and deduplication tools; the b2sum command available under Linux computes a 512-bit BLAKE2b by default.
The special case of passwords
Why a bare SHA-256 is not suitable
A password is never stored in the clear. A fingerprint is stored, and at each connection the fingerprint of the entered password is recomputed to compare it with the one recorded. The beginner's reflex is to use SHA-256. It leads to a database that is opened in a few hours.
The reason lies in a quality of SHA-256 that here becomes a defect: its speed. A gaming graphics card computes several billion SHA-256 fingerprints per second — order of magnitude observed in 2026, rising with each generation of hardware. Since the passwords actually chosen by users concentrate on a restricted set of candidates, going through lists of several hundred million already-leaked passwords is immediate. Added to this is the effect of determinism: two accounts having the same password present the same fingerprint, which is read directly in the database and points out the most widespread passwords. Finally, rainbow tables, which keep in condensed form chains of computations done in advance, make it possible to recover a password by trading storage for computation time, without redoing the attack from scratch.
The salt
The salt is a random value, different for each account, drawn at the moment of registration. It is not secret and is stored alongside the fingerprint, in the same database. The hash function is applied to the combination of the salt and the password. Two effects follow from this: the precomputed tables become unusable, since one would be needed per salt; and two accounts sharing the same password receive different fingerprints, which removes the direct reading mentioned above. The salt does not, on the other hand, slow down the attack on a single, targeted account.
The pepper
The pepper is a secret value, identical for the whole application, also mixed with the password before hashing, but which is not stored in the database: it resides in the configuration of the application server, or even in a hardware security module. If only the database leaks — a frequent case with an SQL injection — the attacker does not have the element needed to test their candidates. The counterpart is operational: changing the pepper invalidates all the existing fingerprints, and how to rotate it must be planned. The pepper is an additional defense, never a replacement for the salt or for a suitable function.
Dedicated functions
The right answer to the speed problem is not to tinker with repetitions of SHA-256, but to use a function designed for password storage, whose computation cost is adjustable.
- bcrypt, derived from the Blowfish encryption algorithm, is tuned by a cost factor that doubles the computation time at each increment. A particularity to be aware of: it only takes into account the first 72 bytes of the input.
- scrypt was designed to be costly in memory as much as in computation time, in order to hinder attacks carried out on graphics cards or on specialized circuits, whose memory is the scarce resource.
- Argon2 won the Password Hashing Competition in 2015. It comes in three variants, Argon2d, Argon2i and Argon2id; it is Argon2id that is recommended by default. Three parameters are tuned: the memory used, the number of passes and the degree of parallelism.
- PBKDF2 (Password-Based Key Derivation Function 2) is older and relies on the repetition of a keyed pseudo-random function, in practice HMAC. It resists specialized hardware less well than the previous ones, but remains required by some compliance frameworks.
The tuning of the parameters depends on the hardware and the load: there is no universal value, and figures copied from an article age badly. The practicable rule consists of measuring on the target server and keeping the highest cost that the application can bear at peak connections, then reevaluating this measurement periodically. Two points hold for all these functions: use the implementation provided by the standard library of the language rather than writing one, and compare fingerprints with a constant-time comparison function, so that the duration of the response does not inform the attacker.
Points of vigilance and the rest of the path
The commands to remember for everyday use fit in a few lines: sha256sum fichier and sha256sum -c SHA256SUMS under Linux, Get-FileHash chemin under Windows, openssl dgst -sha256 fichier when a less common algorithm is needed.
- A fingerprint is not a secret: it protects integrity, never confidentiality. Publishing the fingerprint of a sensitive piece of data often amounts to publishing the data if it is guessable.
- A fingerprint is verified by automatic comparison, not by looking at the first and last characters.
- A fingerprint different from the one expected does not always indicate an attack: text encoding, line endings, an archive compared to its decompressed content are the most frequent causes.
- An unsigned fingerprint file only demonstrates the absence of accidental corruption.
- MD5 and SHA-1 are to be set aside as soon as an adversary can choose the hashed content; SHA-256 is the default choice for integrity.
- For a password, no fast function is suitable: Argon2id, scrypt or bcrypt, with a unique salt per account.
The natural continuation of this path deals with three subjects that all rely on hashing: the electronic signature and the verification of a public key, message authentication codes of the HMAC type and the tokens that derive from them, and key derivation functions, which turn a password into an encryption key.
The original text of this article was not preserved by the web archives: the capture of the page stops before the body. Only its introduction survives, taken up here as an opening. The rest was rewritten on September 9, 2026, then proofread and corrected point by point.
