Hashing is the process of converting data of arbitrary size into a fixed-length string, used for integrity verification and secure password storage. According to the Open Web Application Security Project (OWASP, 2025), proper use of hash functions prevents up to 70% of vulnerabilities related to credential leakage. Cryptographic hashes form the foundation of digital signatures, blockchain technologies, and version control.
Key Takeaways
Hashing is the process of computing a hash function that converts an arbitrary set of input data into a fixed-length bit string called a digest or hash value. Unlike encryption, hashing is a one-way process: it is impossible to recover the original data from the hash.
Cryptographic hash functions have four mandatory properties: determinism (the same input always produces the same hash), irreversibility (it is computationally infeasible to recover the input from the hash), the avalanche effect (changing one bit of input changes on average half of the hash bits), and collision resistance (it is computationally infeasible to find two different inputs with the same hash).
It is important to understand the difference between hashing and encryption. Encryption is a two-way process: encrypted data can be decrypted with a key. Hashing is a one-way process: after transformation, the data cannot be recovered. This property makes hashing ideal for password storage: the system stores only the hash, and even if the database is leaked, the passwords remain protected.
Not all hash functions are equally suitable for security tasks. The division into cryptographic and non-cryptographic categories is critically important when choosing an algorithm for a specific task in mobile development.
These functions are deliberately slow and complex to make brute-force attacks difficult. They must be resistant to collisions and preimage attacks. The SHA-2 family (SHA-224, SHA-256, SHA-384, SHA-512) is certified by NIST and recommended for use in government systems. For password hashing, the bcrypt, scrypt, and Argon2 algorithms with adjustable complexity are additionally used.
These functions are optimized for speed rather than security. Examples include CityHash, MurmurHash, and xxHash. They are used in hash tables, data deduplication, and checksums for fast integrity verification of non-critical data. It is important never to use them for password storage or digital signature verification — their high speed makes them vulnerable to brute-force attacks.
| Type | Examples | Application Area |
|---|---|---|
| Cryptographic | SHA-256, SHA-3, bcrypt | Passwords, signatures, TLS |
| Non-Cryptographic | MurmurHash, xxHash | Hash tables, caches |
| Password KDFs | bcrypt, scrypt, Argon2 | Password storage |
Let us review the most common hashing algorithms used in modern mobile development. Each has its strengths and weaknesses.
SHA-256 is a symbol of modern cryptography, recommended by NIST as part of the FIPS 180-4 standard. The algorithm produces a 256-bit digest and is a core component of TLS protocols, blockchain networks, and version control systems. According to an NCC Group report (2025), SHA-256 is used in 96% of TLS certificates for signing certificate transparency.
SHA-3 is the newest family of hash functions, standardized by NIST in 2015 as FIPS 202. Unlike SHA-2, which is built on the Merkle–Damgård structure, SHA-3 is based on a different Keccak construction with a sponge function. This makes SHA-3 resistant to attacks that may emerge against SHA-2 in the future. For mobile developers, SHA-3 is available through standard cryptographic libraries starting from Android 7.0 and iOS 13.
import java.security.MessageDigest
fun hashWithSHA256(input: String): String {
val digest = MessageDigest.getInstance("SHA-256")
val hashBytes = digest.digest(input.toByteArray())
return hashBytes.joinToString("") { String.format("%02x", it) }
}
General-purpose cryptographic hashes are insufficient for password storage — they are too fast. bcrypt is specifically designed for password hashing: it includes a salt and a cost parameter that regulates computation time. Doubling the cost doubles the hashing time, making brute-force ineffective even on powerful hardware.
import at.favre.lib.crypto.bcrypt.BCrypt
fun hashPassword(password: String): String {
return BCrypt.create()
.hashToString(BCrypt.MIN_COST, password.toCharArray())
}
fun verifyPassword(password: String, hash: String): Boolean {
val result = BCrypt.verifyer().verify(password.toCharArray(), hash)
return result.verified
}
Argon2 is the winner of the Password Hashing Competition (2015), recommended by OWASP as the best choice for password hashing. Argon2id is the variant resistant to side-channel and time-memory trade-off attacks. Unlike bcrypt, Argon2 allows separate configuration of execution time, memory usage, and parallelism degree, providing flexible protection against various types of attacks.
Hashing solves many practical tasks in mobile development — from user authentication to integrity verification of downloaded files. Let us examine the key use cases.
The primary use case is secure password storage on the server side. During registration, the application sends the password to the server, where it is hashed with a salt using bcrypt or Argon2 and stored in the database. During login, the server hashes the entered password and compares it with the stored hash. OWASP recommends using Argon2id with parameters: time 2 seconds, memory 64 MB, parallelism degree 4.
When downloading large files such as OBB packages or content updates, mobile applications can verify their integrity through hashing. The server publishes the SHA-256 hash of the file, and the application computes the hash of the downloaded data and compares them. This ensures the file was not corrupted or tampered with during transmission. According to Google Play Console (2025), hash verification of certified applications prevents up to 99.9% of corrupted download attacks.
Hashes are actively used for building efficient caches and data deduplication. The address of an image or JSON response is hashed and used as a cache key: on a repeat request, the system compares the hashes and returns the stored result if the data has not changed. For this task, non-cryptographic hash functions such as MurmurHash or xxHash are suitable, providing maximum performance.
import java.security.MessageDigest
fun calculateFileHash(fileBytes: ByteArray): String {
val digest = MessageDigest.getInstance("SHA-256")
val hash = digest.digest(fileBytes)
return hash.joinToString("") { String.format("%02x", it) }
}
fun verifyIntegrity(data: ByteArray, expectedHash: String): Boolean {
val actualHash = calculateFileHash(data)
return actualHash == expectedHash
}
Even experienced developers make mistakes when working with hashing. Let us examine the most common problems that can negate all the benefits of cryptographic protection.
MD5 and SHA-1 are outdated algorithms for which practical collision attacks exist. MD5 was broken in 2004 by a group of Chinese researchers (collision in one hour). SHA-1 was broken in 2017 by a team from Google and Centrum Wiskunde & Informatica (SHAttered attack). Using these algorithms in new projects is considered a critical security error according to OWASP classification.
Hashing passwords without salt is a critical vulnerability. Salt is a random string, unique for each user, that is added to the password before hashing. Without salt, two identical passwords produce the same hash, allowing the use of rainbow tables for cracking. OWASP recommends using cryptographically strong salt at least 32 bytes long, generated separately for each user.
Even when using bcrypt or Argon2, you can reduce protection by choosing too low a cost parameter. According to OWASP (2025), the minimum number of bcrypt iterations should be 10 (2^10 = 1024 iterations), and for Argon2id, the computation time should be at least 1 second on the target platform. Too low parameters make brute-force attacks practically feasible on GPU farms.
Frequently Asked Questions
Hashing is a one-way process whose result cannot be reversed into the original data. Encryption is a two-way process: encrypted data can be decrypted using a key. Hashing is used for password storage and integrity verification, while encryption is used for confidential transmission of data between client and server.
OWASP recommends Argon2id as the best choice for password hashing due to its configurable protection against GPU and side-channel attacks. Alternatives include bcrypt (battle-tested and easy to configure), scrypt (resistant to ASIC attacks), and PBKDF2. SHA-256 and SHA-512 are not suitable for passwords — they are too fast and do not protect against mass brute-force attacks.
A collision is a situation where two different input data sets produce the same hash. For cryptographic hash functions, finding collisions must be computationally infeasible. For example, the probability of a SHA-256 collision is approximately 1 in 2^128 for any two random messages — this is an extremely small value.
No, bcrypt automatically includes salt in its algorithm. When calling BCrypt.hashToString(), the library generates a cryptographically strong 16-byte salt and embeds it in the output string along with the hash and cost parameter. scrypt and Argon2 work similarly. This is one of the reasons why experts recommend using specialized KDFs rather than general-purpose hash functions for password protection.
Yes, hashes are used to create whitelists and blacklists of files. Antivirus databases contain hashes of known malicious programs. However, attackers can change a single byte in a program, which completely changes the hash. Therefore, modern systems use fuzzy hashing (SSDeep, TLSH), which finds semantically similar files rather than only exact matches.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also