### Java Usage Example for Argon2Kt Source: https://context7.com/lambdapioneer/argon2kt/llms.txt Demonstrates how to use the Argon2Kt library from Java code for hashing and verifying passwords. Ensure the Argon2Kt library is correctly included in your Java project. ```java import com.lambdapioneer.argon2kt.Argon2Kt; import com.lambdapioneer.argon2kt.Argon2KtResult; import com.lambdapioneer.argon2kt.Argon2Mode; public class PasswordHasher { public void hashAndVerifyPassword(String password, String salt) { // Initialize Argon2Kt final Argon2Kt argon2Kt = new Argon2Kt(); // Hash the password with default parameters final Argon2KtResult hashResult = argon2Kt.hash( Argon2Mode.ARGON2_ID, password.getBytes(), salt.getBytes() ); // Get the encoded output for storage final String encodedOutput = hashResult.encodedOutputAsString(); System.out.println("Encoded hash: " + encodedOutput); // Verify the password final boolean verificationResult = argon2Kt.verify( Argon2Mode.ARGON2_ID, encodedOutput, password.getBytes() ); System.out.println("Verification result: " + verificationResult); } } ``` -------------------------------- ### Hash and Verify Password with Argon2Kt Source: https://github.com/lambdapioneer/argon2kt/blob/main/README.md Demonstrates initializing Argon2Kt, hashing a password with specified parameters, and verifying it against an encoded string. Ensure the native library is loaded before use. ```kotlin // initialize Argon2Kt and load the native library val argon2Kt = Argon2Kt() // hash a password val hashResult : Argon2KtResult = argon2Kt.hash( mode = Argon2Mode.ARGON2_I, password = passwordByteArray, salt = saltByteArray, tCostInIterations = 5, mCostInKibibyte = 65536 ) println("Raw hash: ${hashResult.rawHashAsHexadecimal()}") println("Encoded string: ${hashResult.encodedOutputAsString()}") // verify a password against an encoded string representation val verificationResult : Boolean = argon2Kt.verify( mode = Argon2Mode.ARGON2_I, encodedString = hashResult.encodedOutputAsString(), password = passwordByteArray, ) ``` -------------------------------- ### Initialize and Hash Passwords with Argon2Kt Source: https://context7.com/lambdapioneer/argon2kt/llms.txt Initialize Argon2Kt to load the native library (off the main thread) and then use the hash() method. Ensure the salt is at least 8 bytes. Recommended settings for Argon2id are provided. ```kotlin import com.lambdapioneer.argon2kt.Argon2Kt import com.lambdapioneer.argon2kt.Argon2Mode import com.lambdapioneer.argon2kt.Argon2Version // Initialize Argon2Kt (loads native library - run off main thread) val argon2Kt = Argon2Kt() // Hash a password with recommended settings val password = "mySecurePassword123" val salt = "randomSalt12345678".toByteArray() // Salt must be at least 8 bytes val hashResult = argon2Kt.hash( mode = Argon2Mode.ARGON2_ID, // Recommended: balanced security password = password.toByteArray(), salt = salt, tCostInIterations = 5, // Number of iterations mCostInKibibyte = 65536, // 64 MiB memory cost parallelism = 2, // Parallel threads hashLengthInBytes = 32, // 256-bit output version = Argon2Version.V13 // Latest version ) // Get results in different formats val rawHashHex = hashResult.rawHashAsHexadecimal() // Output: "A1B2C3D4E5F6..." (64 hex characters for 32 bytes) val rawHashBytes = hashResult.rawHashAsByteArray() // Output: ByteArray of 32 bytes val encodedString = hashResult.encodedOutputAsString() // Output: "$argon2id$v=19$m=65536,t=5,p=2$cmFuZG9tU2FsdDEyMzQ1Njc4$..." ``` -------------------------------- ### Argon2 Versions V13 and V10 Hashing Source: https://context7.com/lambdapioneer/argon2kt/llms.txt Demonstrates hashing with Argon2 version V13 (recommended) and V10 for backward compatibility. Ensure correct mode, password, salt, and cost parameters are provided. ```kotlin import com.lambdapioneer.argon2kt.Argon2Kt import com.lambdapioneer.argon2kt.Argon2Mode import com.lambdapioneer.argon2kt.Argon2Version val argon2Kt = Argon2Kt() // Use V13 (default and recommended) val hashV13 = argon2Kt.hash( mode = Argon2Mode.ARGON2_I, password = "password".toByteArray(), salt = "somesalt".toByteArray(), tCostInIterations = 2, mCostInKibibyte = 65536, version = Argon2Version.V13 ) // Encoded output includes version: $argon2i$v=19$m=65536,t=2,p=1$... // Use V10 for backwards compatibility val hashV10 = argon2Kt.hash( mode = Argon2Mode.ARGON2_I, password = "password".toByteArray(), salt = "somesalt".toByteArray(), tCostInIterations = 2, mCostInKibibyte = 65536, version = Argon2Version.V10 ) // Encoded output: $argon2i$m=65536,t=2,p=1$... ``` -------------------------------- ### Configure Argon2 Native Library Build Source: https://github.com/lambdapioneer/argon2kt/blob/main/lib/CMakeLists.txt Sets up the build for the native Argon2 library. It defines the source files and adds the library as a shared object, including compile options and include directories. ```cmake cmake_minimum_required(VERSION 3.6.0) # # Argon2 original native library (argon2native) # project(argon2native C CXX) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Os") set(argon2native_DIR ${CMAKE_CURRENT_LIST_DIR}/src/main/cpp/argon2) file(GLOB argon2native_SOURCES ${argon2native_DIR}/blake2/blake2b.c ${argon2native_DIR}/argon2.c ${argon2native_DIR}/core.c ${argon2native_DIR}/encoding.c ${argon2native_DIR}/ref.c ${argon2native_DIR}/thread.c ) add_library(argon2native SHARED ${argon2native_SOURCES}) target_compile_options(argon2native PRIVATE) target_include_directories(argon2native PUBLIC ${argon2native_DIR}) # Add support for 16kB page size for Android 15. target_link_options(${CMAKE_PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384") ``` -------------------------------- ### Custom SoLoader with ReLinker Source: https://context7.com/lambdapioneer/argon2kt/llms.txt Implement a custom SoLoader using ReLinker for more robust native library loading on devices with problematic loading mechanisms. Ensure ReLinker is added as a dependency. ```kotlin import com.lambdapioneer.argon2kt.Argon2Kt import com.lambdapioneer.argon2kt.SoLoaderShim import com.lambdapioneer.argon2kt.Argon2Mode // import com.getkeepsafe.relinker.ReLinker // Add ReLinker dependency // Custom SoLoader using ReLinker for more robust loading class ReLinkerSoLoader(private val context: Context) : SoLoaderShim { override fun loadLibrary(libname: String) { // ReLinker.loadLibrary(context, libname) // Fallback to system loader for this example System.loadLibrary(libname) } } // Initialize with custom loader val argon2Kt = Argon2Kt(soLoader = ReLinkerSoLoader(applicationContext)) // Verify JNI is working correctly Argon2Kt.assertJniWorking() // Throws if JNI fails // Use normally val result = argon2Kt.hash( mode = Argon2Mode.ARGON2_ID, password = "password".toByteArray(), salt = "saltsalt".toByteArray() ) ``` -------------------------------- ### Configure Argon2 JNI Integration Build Source: https://github.com/lambdapioneer/argon2kt/blob/main/lib/CMakeLists.txt Sets up the build for the JNI integration layer. It defines the source files, adds the library as a shared object, and links it against the native Argon2 library. ```cmake # # JNI integration (argon2jni) # project(argon2jni CXX) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Os") set(argon2jni_DIR ${CMAKE_CURRENT_LIST_DIR}/src/main/cpp/jni) file(GLOB argon2jni_SOURCES ${argon2jni_DIR}/*.cpp ) add_library(argon2jni SHARED ${argon2jni_SOURCES}) target_compile_options(argon2jni PRIVATE) target_include_directories(argon2jni PUBLIC ${argon2jni_DIR}) target_link_libraries(argon2jni argon2native) # Add support for 16kB page size for Android 15. target_link_options(${CMAKE_PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384") ``` -------------------------------- ### Benchmark for Optimal Iteration Count Source: https://context7.com/lambdapioneer/argon2kt/llms.txt Uses Argon2KtBenchmark to find an optimal iteration count for a target hashing time, balancing security and user experience. The optimal value is then used for actual hashing. ```kotlin import com.lambdapioneer.argon2kt.Argon2Kt import com.lambdapioneer.argon2kt.Argon2KtBenchmark import com.lambdapioneer.argon2kt.Argon2Mode val argon2Kt = Argon2Kt() // Find iteration count for ~500ms hashing time val targetTimeMs = 500L val memoryCostKiB = 65536 // 64 MiB val optimalIterations = Argon2KtBenchmark.searchIterationCount( argon2Kt = argon2Kt, argon2Mode = Argon2Mode.ARGON2_ID, targetTimeMs = targetTimeMs, mCostInKibibyte = memoryCostKiB, parallelism = 2, hashLengthInBytes = 32 ) println("Optimal iterations for ${targetTimeMs}ms: $optimalIterations") // Use the optimal value for actual hashing val hashResult = argon2Kt.hash( mode = Argon2Mode.ARGON2_ID, password = "userPassword".toByteArray(), salt = "uniqueSaltValue8".toByteArray(), tCostInIterations = optimalIterations, mCostInKibibyte = memoryCostKiB ) ``` -------------------------------- ### Verify Passwords Against Encoded Hash Source: https://context7.com/lambdapioneer/argon2kt/llms.txt Use the verify() method to check if a password matches a stored encoded Argon2 hash. The encoded string contains all necessary parameters for verification. ```kotlin import com.lambdapioneer.argon2kt.Argon2Kt import com.lambdapioneer.argon2kt.Argon2Mode val argon2Kt = Argon2Kt() // Stored encoded hash from previous hashing operation val storedEncodedHash = "$argon2id$v=19$m=65536,t=2,p=1$c29tZXNhbHQ$CTFhFdXPJO1aFaMaO6Mm5c8y7cJHAph8ArZWb2GRPPc" // Verify the password val passwordToVerify = "password" val isValid = argon2Kt.verify( mode = Argon2Mode.ARGON2_ID, encoded = storedEncodedHash, password = passwordToVerify.toByteArray() ) if (isValid) { println("Password is correct!") } else { println("Invalid password") } ``` -------------------------------- ### Android AsyncTask for Password Hashing with Argon2Kt Source: https://context7.com/lambdapioneer/argon2kt/llms.txt This snippet shows how to implement an AsyncTask to hash passwords securely in the background on Android. It handles the hashing process and returns the result or any exceptions encountered. Ensure Argon2Kt is added as a Gradle dependency. ```kotlin import android.os.AsyncTask import com.lambdapioneer.argon2kt.Argon2Kt import com.lambdapioneer.argon2kt.Argon2KtUtils import com.lambdapioneer.argon2kt.Argon2Mode import com.lambdapioneer.argon2kt.Argon2Version data class HashParams( val password: String, val saltHex: String, val iterations: Int, val memoryKiB: Int, val mode: Argon2Mode, val version: Argon2Version ) data class HashResult( val hashHex: String? = null, val encodedString: String? = null, val timeMs: Long? = null, val error: Exception? = null ) class HashPasswordTask( private val onComplete: (HashResult) -> Unit ) : AsyncTask() { override fun doInBackground(vararg params: HashParams): HashResult { val p = params[0] return try { val startTime = System.nanoTime() val result = Argon2Kt().hash( mode = p.mode, password = p.password.toByteArray(), salt = Argon2KtUtils.decodeAsHex(p.saltHex), tCostInIterations = p.iterations, mCostInKibibyte = p.memoryKiB, version = p.version ) val endTime = System.nanoTime() HashResult( hashHex = result.rawHashAsHexadecimal(), encodedString = result.encodedOutputAsString(), timeMs = (endTime - startTime) / 1_000_000 ) } catch (e: Exception) { HashResult(error = e) } } override fun onPostExecute(result: HashResult) { onComplete(result) } } // Usage HashPasswordTask { result -> result.hashHex?.let { println("Hash: $it") } result.encodedString?.let { println("Encoded: $it") } result.timeMs?.let { println("Time: ${it}ms") } result.error?.let { println("Error: ${it.message}") } }.execute(HashParams( password = "userPassword", saltHex = "0102030405060708090a0b0c0d0e0f10", iterations = 3, memoryKiB = 65536, mode = Argon2Mode.ARGON2_ID, version = Argon2Version.V13 )) ``` -------------------------------- ### Hex Encoding Utilities for ByteArrays Source: https://context7.com/lambdapioneer/argon2kt/llms.txt Provides utility functions for converting between ByteArrays and hexadecimal strings using Argon2KtUtils. Supports decoding hex strings and encoding raw hashes to hex in both uppercase and lowercase. ```kotlin import com.lambdapioneer.argon2kt.Argon2KtUtils import com.lambdapioneer.argon2kt.Argon2Kt import com.lambdapioneer.argon2kt.Argon2Mode // Decode hex string to ByteArray val hexSalt = "736f6d6573616c74" // "somesalt" in hex val saltBytes = Argon2KtUtils.decodeAsHex(hexSalt) println("Decoded salt: ${String(saltBytes)}") // Output: somesalt // You can use hex-encoded salts directly with Argon2Kt val argon2Kt = Argon2Kt() val hashResult = argon2Kt.hash( mode = Argon2Mode.ARGON2_ID, password = "password".toByteArray(), salt = Argon2KtUtils.decodeAsHex("0102030405060708090a0b0c0d0e0f10"), tCostInIterations = 2, mCostInKibibyte = 65536 ) // Get hash as hex (uppercase by default) val hashHexUpper = hashResult.rawHashAsHexadecimal(uppercase = true) println("Hash (uppercase): $hashHexUpper") // Get hash as hex (lowercase) val hashHexLower = hashResult.rawHashAsHexadecimal(uppercase = false) println("Hash (lowercase): $hashHexLower") ``` -------------------------------- ### Add Argon2Kt Dependency to Gradle Source: https://github.com/lambdapioneer/argon2kt/blob/main/README.md Include this dependency in your app's build.gradle file to use the Argon2Kt library. ```groovy implementation 'com.lambdapioneer.argon2kt:argon2kt:1.6.0' ``` -------------------------------- ### Direct ByteBuffer Usage for Secure Memory Source: https://context7.com/lambdapioneer/argon2kt/llms.txt Utilizes direct-allocated ByteBuffers for password and salt to prevent sensitive data from lingering in JVM heap memory. Buffers are manually wiped after use. ```kotlin import com.lambdapioneer.argon2kt.Argon2Kt import com.lambdapioneer.argon2kt.Argon2Mode import java.nio.ByteBuffer import java.security.SecureRandom val argon2Kt = Argon2Kt() // Allocate direct ByteBuffers for password and salt val passwordBytes = "secretPassword".toByteArray() val passwordBuffer = ByteBuffer.allocateDirect(passwordBytes.size) passwordBuffer.put(passwordBytes) val saltBytes = ByteArray(16) SecureRandom().nextBytes(saltBytes) val saltBuffer = ByteBuffer.allocateDirect(saltBytes.size) saltBuffer.put(saltBytes) try { // Hash using direct ByteBuffers val hashResult = argon2Kt.hash( mode = Argon2Mode.ARGON2_ID, password = passwordBuffer, salt = saltBuffer, tCostInIterations = 3, mCostInKibibyte = 65536 ) // Use the hash result val encodedHash = hashResult.encodedOutputAsString() println("Encoded: $encodedHash") } finally { // Wipe sensitive buffers from memory // The library provides internal wipeDirectBuffer() method // For manual wiping: passwordBuffer.rewind() val wipeBytes = ByteArray(passwordBuffer.capacity()) SecureRandom().nextBytes(wipeBytes) passwordBuffer.put(wipeBytes) saltBuffer.rewind() SecureRandom().nextBytes(wipeBytes.copyOf(saltBuffer.capacity())) saltBuffer.put(wipeBytes.copyOf(saltBuffer.capacity())) } ``` -------------------------------- ### Argon2Exception Handling Source: https://context7.com/lambdapioneer/argon2kt/llms.txt Catch and handle Argon2-specific errors using Argon2Exception, which provides detailed error codes for debugging. Note that password mismatches return false, not an exception. ```kotlin import com.lambdapioneer.argon2kt.Argon2Kt import com.lambdapioneer.argon2kt.Argon2Mode import com.lambdapioneer.argon2kt.Argon2Exception val argon2Kt = Argon2Kt() try { // This will fail - salt is too short (minimum 8 bytes) val result = argon2Kt.hash( mode = Argon2Mode.ARGON2_I, password = "password".toByteArray(), salt = "short".toByteArray() // Only 5 bytes! ) } catch (e: Argon2Exception) { println("Argon2 error: ${e.message}") // Output: "ARGON2_SALT_TOO_SHORT (-6)" } try { // Verification with malformed encoded string val valid = argon2Kt.verify( mode = Argon2Mode.ARGON2_I, encoded = "\$argon2i\$v=19\$m=65536,t=2,p=1\$\$invalidhash", password = "password".toByteArray() ) } catch (e: Argon2Exception) { println("Verification error: ${e.message}") // Output: "ARGON2_SALT_TOO_SHORT (-6)" } // Password mismatch returns false, not an exception val mismatch = argon2Kt.verify( mode = Argon2Mode.ARGON2_I, encoded = "\$argon2i\$v=19\$m=65536,t=2,p=1\$c29tZXNhbHQ\$wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", password = "wrongpassword".toByteArray() ) println("Password valid: $mismatch") // Output: false ``` -------------------------------- ### Select Argon2 Hash Variant (Mode) Source: https://context7.com/lambdapioneer/argon2kt/llms.txt Choose the appropriate Argon2 mode based on security requirements. ARGON2_ID is recommended for password hashing due to its balance of security and resistance to side-channel attacks. ```kotlin import com.lambdapioneer.argon2kt.Argon2Kt import com.lambdapioneer.argon2kt.Argon2Mode val argon2Kt = Argon2Kt() val password = "password".toByteArray() val salt = "somesalt".toByteArray() // ARGON2_D: Data-dependent memory access (NOT side-channel resistant) // Best for backend systems without side-channel attack risk val hashD = argon2Kt.hash( mode = Argon2Mode.ARGON2_D, password = password, salt = salt, tCostInIterations = 2, mCostInKibibyte = 65536 ) // ARGON2_I: Data-independent memory access (side-channel resistant) // Best for key derivation where side-channels are a concern val hashI = argon2Kt.hash( mode = Argon2Mode.ARGON2_I, password = password, salt = salt, tCostInIterations = 2, mCostInKibibyte = 65536 ) // ARGON2_ID: Hybrid mode (RECOMMENDED for password hashing) // First half uses ARGON2_I, second half uses ARGON2_D val hashId = argon2Kt.hash( mode = Argon2Mode.ARGON2_ID, password = password, salt = salt, tCostInIterations = 2, mCostInKibibyte = 65536 ) println("Argon2d: ${hashD.rawHashAsHexadecimal()}") println("Argon2i: ${hashI.rawHashAsHexadecimal()}") println("Argon2id: ${hashId.rawHashAsHexadecimal()}") ``` -------------------------------- ### BibTex Reference for Argon2Kt Source: https://github.com/lambdapioneer/argon2kt/blob/main/README.md Use this BibTex snippet to cite Argon2Kt in academic papers or documentation. ```bibtex @misc{hugenroth2019argon2kt, author={{Daniel Hugenroth}}, title={Argon2Kt}, year={2019}, url={https://github.com/lambdapioneer/argon2kt}, } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.