Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: December 28, 2023
The MD5 (Message-Digest Algorithm 5) hash is a widely used cryptographic hash function. Although MD5 is not recommended for cryptographic security due to vulnerabilities, it’s still used for other purposes.
In this tutorial, we’ll explore how to generate an MD5 hash in Kotlin.
MD5 is a cryptographic hash function that transforms any input data into a fixed-size, 128-bit (16-byte) hash, typically represented as a 32-character hexadecimal number. This process is one-way, meaning the original data can’t be retrieved from the hash.
There are a few key characteristics to note about this algorithm:
We also need to be aware of the limitations and potential vulnerabilities of this algorithm when used in certain ways:
Despite its known security vulnerabilities, MD5 is still used for:
While efficient, MD5’s security issues limit its use to non-critical applications. For secure hashing needs, algorithms like SHA-256 are recommended due to their robustness against vulnerabilities that affect MD5.
Kotlin has a straightforward way of handling MD5 hashing by utilizing Java’s MessageDigest class. We’ll create an extension function for the String class that will perform the MD5 hashing:
@OptIn(ExperimentalStdlibApi::class)
fun String.md5(): String {
val md = MessageDigest.getInstance("MD5")
val digest = md.digest(this.toByteArray())
return digest.toHexString()
}
This function first obtains an instance of MessageDigest for MD5, then computes the digest of our string converted to a ByteArray, before finally converting the resulting MD5 digest ByteArray to a String. We use toHexString() – an experimental function introduced in Kotlin 1.9 – to convert the ByteArray into a more typical representation of the digest: a hexadecimal string. Because this function is still experimental, we must opt-in to use it.
To verify our function, let’s write a JUnit test to ensure it’s working as expected:
@Test
fun `Calling extension md5 should return a md5 hash`() {
val stringToBeHashed = "Hello, Baeldung!"
val expectedHash = "6469a4ea9e2753755f5120beb51587f8"
val calculatedHash = stringToBeHashed.md5()
assertEquals(expectedHash, calculatedHash)
}
This test confirms that our md5() function calculates the MD5 hash of “Hello, Baeldung!” as “6469a4ea9e2753755f5120beb51587f8”, which we computed ahead of time.
Similarly to what we’ve done with a String in the previous section, we can apply MD5 hashing to a File. Calculating the MD5 hash of a file is a common way to verify the file’s integrity. Computing the MD5 hash of a file specifically means we’re computing the hash of the file’s contents.
Let’s define a function that calculates a file’s MD5 hash in Kotlin:
@OptIn(ExperimentalStdlibApi::class)
fun File.md5(): String {
val md = MessageDigest.getInstance("MD5")
val digest = md.digest(this.readBytes())
return digest.toHexString()
}
Let’s also write a unit test to ensure our new function works. We’ll use test_md5.txt as our example file, which contains:
Hello, Baeldung! I'm a file!
Now, let’s have a look at the test code:
@Test
fun `Calling extension md5 on a file should return a md5 hash`() {
val fileToBeHashed = File("src/test/resources/test_md5.txt")
val expectedHash = "ef948f943cdba8514ed5aab7592a904d"
val calculatedHash = fileToBeHashed.md5()
assertEquals(expectedHash, calculatedHash)
}
This unit test validates that our md5() function hashes our test_md5.txt file to “ef948f943cdba8514ed5aab7592a904d”, which we also computed ahead of time.
In this article, we’ve demonstrated a simple and effective way to generate MD5 hashes in Kotlin by borrowing Java’s MessageDigest class. Remember, while MD5 is quick and useful for certain applications, it’s not suitable for security-sensitive operations. For those, we should consider more secure hashing algorithms like SHA-256.