How to decrypt a SHA-256 encrypted string?
Categories:
Understanding and Handling SHA-256 Hashes in Java

This article clarifies a common misconception: SHA-256 is a one-way hashing algorithm, not an encryption method. Learn why decryption is impossible and how to correctly verify SHA-256 hashes in Java.
A frequent question in cryptography is "How do I decrypt a SHA-256 encrypted string?" This question stems from a fundamental misunderstanding of what SHA-256 actually is. SHA-256 (Secure Hash Algorithm 256-bit) is a cryptographic hash function, not an encryption algorithm. The distinction is crucial: encryption is a two-way process (encrypt and decrypt), while hashing is a one-way process (hash, but cannot un-hash).
Hashing vs. Encryption: The Core Difference
To truly understand why SHA-256 cannot be 'decrypted,' it's essential to grasp the difference between hashing and encryption. Encryption aims to transform data into an unreadable format that can later be reverted to its original state using a key. Hashing, on the other hand, takes an input (or 'message') and returns a fixed-size string of bytes, typically a 'digest' or 'fingerprint.' This process is designed to be irreversible.
flowchart TD A[Original Data] --> B{Hashing Function (e.g., SHA-256)} B --> C[Fixed-Size Hash Value] C --X Cannot Reverse X--> A D[Original Data] --> E{Encryption Algorithm + Key} E --> F[Ciphertext] F --> G{Decryption Algorithm + Key} G --> D
Comparison of Hashing (one-way) and Encryption (two-way) processes.
The output of a SHA-256 hash function is a unique, fixed-length string (256 bits, usually represented as a 64-character hexadecimal string) that is computationally infeasible to reverse engineer back to the original input. Even a tiny change in the input data will result in a drastically different hash value. This property makes hash functions ideal for data integrity checks and password storage, but unsuitable for data confidentiality (which is where encryption comes in).
Why SHA-256 is Irreversible
SHA-256 is designed with several properties that make it irreversible:
- One-Way Function: There's no mathematical inverse function to SHA-256.
- Information Loss: The hashing process involves mathematical operations that discard information, making it impossible to reconstruct the original input from the hash alone.
- Collision Resistance: While theoretically possible, finding two different inputs that produce the same hash output (a 'collision') is extremely difficult for strong hash functions like SHA-256. However, even if a collision were found, it wouldn't reveal the original input, only another input that produces the same hash.
Correct Usage: Verifying SHA-256 Hashes in Java
Since you cannot decrypt a SHA-256 hash, the correct approach is to verify it. This typically involves hashing a new input and comparing the resulting hash with a previously stored hash. If the hashes match, it confirms that the original data (or password) is the same. This is commonly used for password authentication or checking file integrity.
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class Sha256Verifier {
public static String hashString(String originalString) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] encodedhash = digest.digest(
originalString.getBytes(StandardCharsets.UTF_8));
return bytesToHex(encodedhash);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
private static String bytesToHex(byte[] hash) {
StringBuilder hexString = new StringBuilder(2 * hash.length);
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if(hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
public static boolean verifyHash(String originalInput, String storedHash) {
String newHash = hashString(originalInput);
return newHash.equals(storedHash);
}
public static void main(String[] args) {
String originalData = "MySecretPassword123";
String dataToVerify = "MySecretPassword123";
String incorrectData = "WrongPassword";
// 1. Hash the original data
String hashedData = hashString(originalData);
System.out.println("Original Data: " + originalData);
System.out.println("SHA-256 Hash: " + hashedData);
// 2. Verify with correct input
boolean isVerifiedCorrect = verifyHash(dataToVerify, hashedData);
System.out.println("Verification with correct input: " + isVerifiedCorrect);
// 3. Verify with incorrect input
boolean isVerifiedIncorrect = verifyHash(incorrectData, hashedData);
System.out.println("Verification with incorrect input: " + isVerifiedIncorrect);
// Example with a different string
String anotherString = "Hello World";
String anotherHash = hashString(anotherString);
System.out.println("\nAnother String: " + anotherString);
System.out.println("SHA-256 Hash: " + anotherHash);
}
}
In the example above, hashString
takes an input string and returns its SHA-256 hash as a hexadecimal string. The verifyHash
method then re-hashes a given input and compares it to a known (stored) hash. This is the correct and secure way to work with SHA-256 hashes.