How can I determine the hashing algorithm used when I know the salt and plain-text password?
I have a database table with user records containing password-hash and password-salt columns. I know the plain-text password for one of these users. The salt column is defined as varchar(20) and the hash column as varchar(64).
Is it possible to identify the specific hashing algorithm used based on this information? My goal is to generate strong initial passwords for new users, as the current software only provides weak ones. I need to understand the hashing algorithm to create passwords that will work with the existing authentication system.
When you know both the salt and plain-text password, you can determine the hashing algorithm by systematically testing different algorithms with your known values and comparing the resulting hash to the stored hash. The hash length (varchar(64)) strongly suggests SHA-256, as it produces exactly 64 hexadecimal characters, while the salt length (varchar(20)) is compatible with various modern hashing algorithms. You’ll need to test common algorithms systematically, starting with those that match your hash length format.
Contents
- Understanding Hash Length Clues
- Systematic Algorithm Testing Process
- Common Hashing Algorithms and Their Signatures
- Practical Implementation Steps
- Tools for Algorithm Identification
- Generating Compatible Strong Passwords
Understanding Hash Length Clues
The length of your stored hash (varchar(64)) provides the most immediate clue about the potential algorithm. Hash lengths are determined by the underlying cryptographic function:
- 64 characters: Typically indicates SHA-256 (256 bits = 32 bytes = 64 hex characters)
- 128 characters: Typically indicates SHA-512 (512 bits = 64 bytes = 128 hex characters)
- Variable length: May indicate bcrypt, scrypt, or Argon2 (which use Base64 encoding)
Important note: The fact that your hash column is exactly 64 characters strongly suggests SHA-256, but this isn’t definitive confirmation. Some implementations might truncate or format hashes differently.
The salt length (varchar(20)) is also informative:
- Modern best practice suggests salts should be 16-32 bytes
- Your varchar(20) limit could accommodate various salt sizes
- The actual salt content (not just its storage length) matters more for algorithm identification
Systematic Algorithm Testing Process
When you have both the salt and plain-text password, you can follow this systematic approach:
Step 1: Analyze Hash Format
Examine the stored hash for identifying patterns:
- Does it contain dollar signs (algorithmhash`?
- Is it purely hexadecimal (0-9, a-f)?
- Does it contain other characters (/, +, =) suggesting Base64 encoding?
Step 2: Generate Candidate Hashes
For each suspected algorithm, generate a hash using:
- Your known plain-text password
- The stored salt value
- Common parameter values (like iteration counts for PBKDF2, cost factors for bcrypt)
Step 3: Compare Results
Compare your generated hash with the stored hash. A match confirms the algorithm.
According to security experts, “Check your output size, eliminate non-matching, then make sure that the rest uses salt, too. Now, on the remaining list, try each of them one by one.”
Common Hashing Algorithms and Their Signatures
SHA-256 Family
- SHA-256: 64 hex characters, no salt prefix
- PBKDF2-HMAC-SHA256: Often 64 characters, may have iteration count
- HMAC-SHA256: 64 characters, requires secret key
Adaptive Key Derivation Functions
- bcrypt: Starts with
$2a$,$2b$, or$2y$, 60 characters total - scrypt: Starts with
$7$, variable length - Argon2: Starts with
$argon2i$,$argon2d$, or$argon2id$
Legacy Unix Algorithms
- crypt(): First 2 characters are salt, rest is hash
- MD5: 32 hex characters (your 64-character hash rules this out)
Practical tip: The OWASP Password Storage Cheat Sheet provides excellent guidance on algorithm characteristics and security levels.
Practical Implementation Steps
Code Implementation Example
Here’s how you might implement this in Python:
import hashlib
import binascii
def test_algorithm(password, salt, stored_hash):
# Test SHA-256
sha256_hash = hashlib.sha256((password + salt).encode()).hexdigest()
if sha256_hash == stored_hash:
return "SHA-256"
# Test PBKDF2-HMAC-SHA256
pbkdf2_hash = binascii.hexlify(
hashlib.pbkdf2_hmac('sha256', password.encode(), salt.encode(), 100000)
).decode()
if pbkdf2_hash == stored_hash:
return "PBKDF2-HMAC-SHA256"
# Add more algorithm tests here...
return "Unknown"
# Usage
password = "known_password"
salt = "from_database_stored_salt"
stored_hash = "64_character_hash_from_database"
algorithm = test_algorithm(password, salt, stored_hash)
print(f"Detected algorithm: {algorithm}")
Database Testing Approach
If you have database access, you can create a test function:
-- Example for PostgreSQL
CREATE OR REPLACE FUNCTION test_password_hash(p_password TEXT, p_salt TEXT, p_hash TEXT)
RETURNS TEXT AS $$
BEGIN
-- Test SHA-256
IF SHA256(p_password || p_salt) = p_hash THEN
RETURN 'SHA-256';
END IF;
-- Test other algorithms...
RETURN 'Unknown';
END;
$$ LANGUAGE plpgsql;
Tools for Algorithm Identification
Hashcat
Hashcat has extensive built-in support for password hashing algorithms. You can use it to test multiple algorithms simultaneously:
# Test with known salt and password
hashcat -m 0 -a 0 hash.txt wordlist.txt
Where -m 0 specifies the hash mode (you can try different modes).
Online Hash Identifiers
Several online tools can help identify algorithms:
Programming Libraries
- Python:
hashlib,passlib,bcrypt - PHP:
hash(),password_hash()functions - JavaScript:
cryptoAPI
Security warning: When using online tools, be cautious about submitting sensitive data like known passwords.
Generating Compatible Strong Passwords
Once you identify the algorithm, you can generate strong passwords that work with your existing system:
Password Requirements Analysis
- Length: Most modern systems support passwords up to 72 bytes
- Character sets: Determine if special characters are supported
- Entropy requirements: Calculate minimum complexity needed
Strong Password Generation
import secrets
import string
def generate_strong_password(length=16):
characters = string.ascii_letters + string.digits + string.punctuation
return ''.join(secrets.choice(characters) for _ in range(length))
# Generate multiple strong passwords
for i in range(10):
print(generate_strong_password())
Implementation Considerations
- Password rotation: Implement regular password changes
- Multi-factor authentication: Add additional security layers
- Rate limiting: Protect against brute force attacks
According to security best practices, “A good rule of thumb is to use a salt that is the same size as the output of the hash function. For example, the output of SHA256 is 256 bits (32 bytes), so the salt should be at least 32 random bytes.”
Conclusion
Determining the hashing algorithm when you know both the salt and plain-text password is entirely achievable through systematic testing. The 64-character hash length strongly suggests SHA-256, but you should verify this by generating test hashes with your known values. Start with the most likely candidates based on hash length and format, then systematically test each one. Once identified, you can generate strong, secure passwords that work with your existing authentication system while significantly improving security. Remember that modern password security requires more than just strong algorithms - implement good password policies, multi-factor authentication, and regular security audits to maintain robust protection.
Sources
- Password Storage - OWASP Cheat Sheet Series
- Get hash algorithm knowing hash, salt and password - Information Security Stack Exchange
- Secure Salted Password Hashing - How to do it Properly
- Salt (cryptography) - Wikipedia
- Password Hashing & Salting - Function and Algorithm Explained - Authgear
- Can you find the salt if you have the original password in plaintext and the hashed version? - Cryptography Stack Exchange
- Add Salt to Hashing: A Better Way to Store Passwords | Auth0
- Password Hashing Algorithms - FusionAuth
- How to find the hashing algorithm used to hash passwords? - Unix & Linux Stack Exchange
- Password Hashing: How to hash and salt passwords in different languages and why it’s important - SuperTokens