C++ libsodium Argon2id for hashing passords

sValentin 81 Reputation points
2024-12-26T21:11:18.82+00:00

I tried to get the equivalent of Java Bouncy Castle Argon2id implementation in C++ using libsodium but the result is different between Java and C++. I used Base64 in java as I need it to be stored in a database as characters and not bytes.

Can someone help me correct what is wrong? One problem that I think is that in C++ I didn't saw an option for Parallelism. Another one might be the way the salt is handled in Java and C++. Another the way the hash is turned into readable/string result.

withParallelism() I thought should only affect the speed, but it also affect the result, as I get different String in the end with different value for it.

public static String hashPassword(String string, String salt) {
	Argon2Parameters.Builder builder = new Argon2Parameters.Builder(Argon2Parameters.
.withSalt(salt.getBytes()).withParallelism(4).withMemoryAsKB(65536).withIterations(4);
	Argon2BytesGenerator generator = new Argon2BytesGenerator();
	generator.init(builder.build());

	byte[] hash = new byte[64];
	generator.generateBytes(string.getBytes(StandardCharsets.

	return Base64.
}

public static void main(String[] args) {
	String password = "ThisIsPassword";
	String salt = "ThisIsSalt";
	String hashedPassword = 
	System.
}
#include <sodium.h>
#include <iostream>
#include <string>
#include <vector>

std::string base64_encode(const unsigned char* input, size_t length) {
	size_t encoded_length = sodium_base64_encoded_len(length, sodium_base64_VARIANT_ORIGINAL);
	std::vector<char> encoded(encoded_length);
	sodium_bin2base64(encoded.data(), encoded_length, input, length, sodium_base64_VARIANT_ORIGINAL);
	return std::string(encoded.data());
}

std::string hashPassword(const std::string& password, const std::string& salt) {
	if (sodium_init() < 0) {
		throw std::runtime_error("Failed to initialize libsodium");
	}
	std::vector<unsigned char> hash(64);
	if (crypto_pwhash(
		hash.data(), hash.size(),
		password.c_str(), password.size(),
		reinterpret_cast<const unsigned char*>(salt.c_str()),
		4,
		65536,
		crypto_pwhash_ALG_ARGON2ID13) != 0) {
		throw std::runtime_error("Failed to hash password");
	}
	return base64_encode(hash.data(), hash.size());
}

int main() {
	std::string password = "ThisIsPassword";
	std::string salt = "ThisIsSalt";
	try {
		std::string hashedPassword = hashPassword(password, salt);
		std::cout << hashedPassword << std::endl;
	}
	catch (const std::exception& e) {
		std::cerr << "Error: " << e.what() << std::endl;
	}
	return 0;
}
Developer technologies | C++
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.