- Introduction
- Javadocs
- Supported platforms
- Requirements
- Version
- How to use
- Supported APIs
- APIs
- License is MIT
- If your project is not a maven project
libsodium-jna is a java library that binds to libsodium C crypto APIs with Java Native Access (JNA). I wrote it because I did not like any of the Java implementation of libsodium. I hope you will find this project useful and fun to use.
Bug reports, suggestions are always welcome!
If you add support to more libsodium APIs, please send me a pull request. If yo do so, please do not forget to update the documentation add unit tests. If you need to generate test vectors, please look at misc/ gen_test_vectors.c
Generated javadocs are available at: https://muquit.github.io/libsodium-jna/
In theory it should work on any platform where native libsodium library works and JVM 1.7+ is available.
The implementation is tested on the following platforms with libsodium v1.0.15 - v1.0.19 with JVM 1.7, 1.8 and jdk11
Platform | JVM |
---|---|
64 bit Windows 7 and 10 | 64 bit JVM |
64 bit MacOS X running Sierra and El Capitan | 64 bit JVM |
64 bit Linux | 64 bit JVM |
32 bit Linux | 32 bit JVM |
It is reported that it works on 32 bit Windows but I personally did not test that | 32 bit JVM |
-
jdk 1.7+. The default
pom.xml
is for jdk upto 1.8. For jdk11, usepom_java11.xml
-
maven must be installed in order to create the jar file. However, it is possible to use the library in a non-maven project.
-
libsodium 1.0.11 or higher. libsodium-jna itself does not enforce version checking but make sure you are using libsodium v 1.0.11 or higher. Please note that the algorithm used in
cryptoPwhashArgon2i()
may change from version to version of libsodium, to make sure, please look at ChangeLog. -
Make sure native libsodium is already installed in the system. This library does not come with native version of libsodium. It is a good idea to compile and install libsodium yourself instead of using one from the Internet.
-
This library does not load any libsodium library from path, rather you have to specify exactly where the library is located.
The current version of libsodium-jna is 1.0.5 (updated on Aug-31-2024), works with libsodium
- 1.0.20
- 1.0.19
- 1.0.18
- 1.0.17
- 1.0.16
- 1.0.15
Please look at ChangeLog for what is changed in the current version.
- Compile and Install libsodium. It is a requirement.
- Download libsodium-1.0.20.tar.gz
- make sure
pkg-config
is installed
Follow the instructions on libsodium doc page on how to compile and install. I do the following on Linux and Mac OS X:
tar -xf libsodium-1.0.20.tar.gz
cd libsodium-1.0.20
./configure
make && make check
sudo make install
sudo ldconfig
Add the following block inside dependencies block:
<!-- As of v1.0.5, libsodium-jna is in the maven central. -->
<dependency>
<groupId>com.muquit.libsodiumjna</groupId>
<artifactId>libsodium-jna</artifactId>
<version>1.0.5</version>
</dependency>
Update: Feb-18-2020. libsodium-jna in Maven central uses Java Native Access v4.2.2. This version of JNA has issues with some version of Microsoft Windows e.g. it does not work in Windows Server 2019. If you are using libsodium-jna from Maven in your project, please update the JNA version to the latest in your pom.xml as follows:
<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.14.0</version>
</dependency>
Note: If you do not use maven, look at the end of the document.
Trunk contains the latest development code but mostly stable. I try not to check-in broken code.
git clone https://github.com/muquit/libsodium-jna.git
cd libsodium-jna
mvn clean install
mvn test
To compile with java 11:
mvn -f pom_java11.xml clean install
mvn -f pom_java11.xml test
To load the project in Eclipse, select File->Import...->Maven->Existing Maven Projects, then Click on Next >, click on Browse... button and select the libsodium-jna directory.
Before making any API calls, native sodium must be loaded from a specific path. Please look at the section Load the libsodium C Library first for details.
The following APIs are implemented at this time.
native libsodium C API | java binding | Description |
---|---|---|
sodium_version_string() |
libsodiumVersionString() |
Return the version of native sodium library |
native libsodium C API | java binding | Description |
---|---|---|
randombytes_buf() |
randomBytes() |
Reruns specified number of unpredictable sequence of bytes |
native libsodium C API | java binding | Description |
---|---|---|
crypto_secretbox_easy() |
public static byte[] cryptoSecretBoxEasy(byte[] message, byte[] nonce, byte[] key) |
Encrypts a message with a key and a nonce |
crypto_secretbox_open_easy() |
public static byte[] cryptoSecretBoxOpenEasy(byte[] cipherText,byte[] nonce, byte[] key) |
Verifies and decrypts an encrypted message produced by cryptoSecretBoxEasy() |
crypto_secretbox_detached() |
public static SodiumSecretBox cryptoSecretBoxDetached(byte[] message, byte[] nonce, byte[] key) |
Encrypts a message with a key and a nonce and returns authentication tag with the encrypted message |
crypto_secretbox_open_detached() |
public static byte[] cryptoSecretBoxOpenDetached(SodiumSecretBox secretBox, byte[] nonce, byte[] key) |
Verifies and decrypts an encrypted message, authentication tag used in cryptoSecretBoxDetached() is needed |
crypto_auth() |
public static byte[] cryptoAuth(byte[] message, byte[] key) |
Computes an authentication tag for a message |
crypto_auth_verify() |
public static boolean cryptoAuthVerify(byte[] mac, byte[] message, byte[] key) |
Verifies the authentication tag for a message |
crypto_secretbox_keybytes() |
public static NativeLong cryptoSecretBoxKeyBytes() |
Length of key. The API will be changed to reutrn int in next version |
crypto_secretbox_noncebytes() |
public static NativeLong cryptoSecretBoxNonceBytes() |
Length of nonce. The API will be changed to reutrn int in next version |
crypto_secretbox_macbytes() |
public static NativeLong cryptoSecretBoxMacBytes() |
Length of authentication code. The API will be changed to reutrn int in next version |
native libsodium C API | java binding | Description |
---|---|---|
crypto_box_keypair() |
public static SodiumKeyPair cryptoBoxKeyPair() |
Randomly generate a private key and a corresponding public key |
crypto_scalarmult_base() |
public static byte[] cryptoPublicKey(byte[] privateKey) |
Compute public key given a private key |
crypto_box_easy() |
public static byte[] cryptoBoxEasy(byte[] message, byte[] nonce, byte[] publicKey, byte[] privateKey) |
Encrypts a message with a recipient's public key, sender's private key and a nonce |
crypto_box_open_easy() |
public static byte[] cryptoBoxOpenEasy(byte[] cipherText, byte[]nonce, byte[] publicKey, byte[] privateKey) |
Verifies and decrypts an encrypted message produced by cryptoBoxEasy() |
crypto_box_seal() |
public static byte[] cryptoBoxSeal(byte[] message, byte[] recipientPublicKey) |
Encrypts a message for a recipient with recipient's public key |
crypto_box_seal_open() |
public static byte[] cryptoBoxSealOpen(byte[] cipherText,byte[] pk, byte[] sk) |
Decrypts an encrypted message with the key pair public key and private key |
crypto_box_noncebytes() |
public static NativeLong cryptoBoxNonceBytes() |
Length of nonce. The API will be changed to reutrn int in next version |
crypto_box_seedbytes() |
public static NativeLong crytoBoxSeedBytes() |
Length of key seed. The API will be changed to reutrn int in next version |
crypto_box_publickeybytes() |
public static NativeLong crytoBoxPublicKeyBytes() |
Length of public key. The API will be changed to reutrn int in next version |
crypto_box_secretkeybytes() |
public static NativeLong crytoBoxSecretKeyBytes() |
Length of private key. The API will be changed to reutrn int in next version |
crypto_box_macbytes() |
public static NativeLong cryptoBoxMacBytes() |
Length of mac. The API will be changed to reutrn int in next version |
crypto_box_sealbytes() |
public static NativeLong cryptoBoxSealBytes() |
Length of seal. The API will be changed to reutrn int in next version |
native libsodium C API | java binding | Description |
---|---|---|
crypto_pwhash() |
public static byte[] cryptoPwhash(byte[] passwd, byte[] salt, long opsLimit, NativeLong memLimit, int algorithm) |
Derives a key from a password. The salt , opslimit , memlimit and algorithm can be specified. |
public static byte[] cryptoPwhashArgon2i(byte[] passwd, byte[] salt) |
Derives a key from a password using Argon2id memory-hard function. Uses default values for opsLimit and memLimit | |
public static byte[] cryptoPwhashScrypt(byte[] passwd, byte[] salt) |
Derives a key from a password using Scrypt | |
crypto_pwhash_str() |
public static String cryptoPwhashStr(byte[] password) |
Derives a US ASCII encoded key from a password using memory-hard, CPU-intensive hash function |
cryupto_pwhash_str_verify() |
public static boolean cryptoPwhashStrVerify(String usAsciiKey, byte[] password) |
Verifies a US ASCII encoded password string generated by cryptoPwhashStr() |
crypto_pwhash_scryptsalsa208sha256() |
public static byte[] cryptoPwhashScryptSalsa208Sha256(byte[] key, byte[] passwd, byte[] salt, long opslimit, NativeLong memlimit) |
|
crypto_pwhash_alg_argon2id13() (default in libsodium v1.0.15) |
public static int cryptoPwhashAlgArgon2id13() |
- |
crypto_pwhash_alg_default() |
public static int cryptoPwhashAlgDefault() |
- |
crypto_pwhash_saltbytes() |
public static int cryptoNumberSaltBytes() |
Length of salt |
crypto_pwhash_saltbytes() |
public static int cryptoPwhashSaltBytes() |
Length of salt |
crypto_pwhash_opslimit_interactive() |
public static long cryptoPwHashOpsLimitInteractive() |
- |
crypto_pwhash_memlimit_interactive() |
public static NativeLong cryptoPwHashMemLimitInterative() |
- |
crypto_pwhash_scryptsalsa208sha256_saltbytes() |
public static NativeLong cryptoPwHashScryptSalsa208Sha256SaltBytes() |
- |
Before making call to any API, the native sodium C library must be loaded explicitly from a specific path. It is possible to load the library from path, however libsodium-jna is designed to load sodium library explicitly from a path.
private static String libraryPath = null;
if (Platform.isMac())
{
// MacOS
libraryPath = "/usr/local/lib/libsodium.dylib";
libraryPath = libraryPath;
logger.info("Library path in Mac: " + libraryPath);
}
else if (Platform.isWindows())
{
// Windows
libraryPath = "C:/libsodium/libsodium.dll";
logger.info("Library path in Windows: " + libraryPath);
}
else
{
// Linux
libraryPath = "/usr/local/lib/libsodium.so";
logger.info("Library path: " + libraryPath);
}
logger.info("loading libsodium...");
SodiumLibrary.setLibraryPath(libraryPath);
// To check the native library is actually loaded, print the version of
// native sodium library
String v = SodiumLibrary.libsodiumVersionString();
logger.info("libsodium version: " + v);
}
If the library could not be loaded Java's RuntimeException
will be thrown.
If the library is loaded successfully, you are ready to make the API calls.
Please look at TestInitializeLibrary.java
to see how the library can be initialized from a static block.
/**
* Return the version of native sodium library. After loading the native C library, it is a good idea
* to make this call to make sure that the expected version of the sodium library is loaded.
*/
public static String libsodiumVersionString()
Make sure to Load the libsodium C Library first
logger.info("libsodium version: " + SodiumLibrary.libsodiumVersionString());
/**
* Return unpredictable sequence of bytes.
*
* Excerpt from libsodium documentation:
*
* - On Windows systems, the RtlGenRandom() function is used
* - On OpenBSD and Bitrig, the arc4random() function is used
* - On recent Linux kernels, the getrandom system call is used (since Sodium 1.0.3)
* - On other Unices, the /dev/urandom device is used
* - If none of these options can safely be used, custom implementations can easily be hooked.
*
* Parameters:
* size Number of random bytes to generate
*
* Return:
* Array of random bytes
*/
public static byte[] randomBytes(int size)
Make sure to Load the libsodium C Library first
// generate 16 bytes of random data
byte[] randomBytes = SodiumLibrary.randomBytes(16);
String hex = SodiumUtils.binary2Hex(salt);
// generate libsodium's standard number of salt bytes
int n = SodiumLibrary.cryptoNumberSaltBytes();
logger.info("Generate " + n + " random bytes");
byte[] salt = SodiumLibrary.randomBytes(n);
logger.info("Generated " + salt.length + " random bytes");
String hex = SodiumUtils.binary2Hex(salt);
logger.info("Random bytes: " + hex);
Excerpt from libsodium documentation:
This operation:
- Encrypts a message with a key and a nonce to keep it confidential
- Computes an authentication tag. This tag is used to make sure that the message hasn't been tampered with before decrypting it.
A single key is used both to encrypt/sign and verify/decrypt messages. For this reason, it is critical to keep the key confidential. The nonce doesn't have to be confidential, but it should never ever be reused with the same key. The easiest way to generate a nonce is to use randombytes_buf().
Make sure to Load the libsodium C Library first
/**
* Encrypts a message with a key and a nonce
*
* Parameters:
* message message bytes to encrypt
* nonce nonce bytes. Generate it by calling public static NativeLong cryptoBoxNonceBytes()
*
* Returns:
* Encrypted cipher text bytes
*
* Throws SodiumLibraryException in case of error
*/
public static byte[] crytoSecretBoxEasy(byte[] message, byte[] nonce, byte[] key)
/**
* Verify and decrypt the message encrypted with crytoSecretBoxEasy()
*
* Parameters:
* cipherText - encrypted bytes
* nonce - nonce bytes used during encryption
* key - key bytes used in encryption
*
* Returns:
* Decrypted message bytes
*
* Throws SodiumLibraryException in case of error
*/
public static byte[] cryptoSecretBoxOpenEasy(byte[] cipherText,byte[] nonce, byte[] key)
Make sure to Load the libsodium C Library first
// don't forget to load the libsodium library first
String message = "This is a message";
// generate nonce
int nonceBytesLength = SodiumLibrary.cryptoSecretBoxNonceBytes().intValue();
byte[] nonceBytes = SodiumLibrary.randomBytes(nonceBytesLength);
byte[] messageBytes = message.getBytes();
// generate the encryption key
byte[] key = SodiumLibrary.randomBytes(SodiumLibrary.cryptoSecretBoxKeyBytes().intValue());
// encrypt
byte[] cipherText = SodiumLibrary.cryptoSecretBoxEasy(messageBytes, nonceBytes, key);
// now decrypt
byte[] decryptedMessageBytes = SodiumLibrary.cryptoSecretBoxOpenEasy(cipherText, nonceBytes, key);
String decryptedMessage;
try
{
decryptedMessage = new String(decryptedMessageBytes, "UTF-8");
System.out.println("Decrypted message: " + decryptedMessageBytes);
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
Make sure to Load the libsodium C Library first
/**
* Randomly generates a secret key and a corresponding public key
*
* Return:
* SodiumKeyPair
*/
public static SodiumKeyPair cryptoBoxKeyPair()
// generate key pair
SodiumKeyPair kp = SodiumLibrary.cryptoBoxKeyPair();
byte[] publicKey = kp.getPublicKey();
byte[] privateKey = kp.getPrivateKey();
String hexPublicKey = SodiumUtils.binary2Hex(publicKey);
String hexPrivateKey = SodiumUtils.binary2Hex(privateKey);
/**
* Alice encrypts a message with recipient's (Bob) public key and
* creates authentication tag with her private key
*
* Parameters:
* message The message to encrypt
* nonce SodiumLibrary.crytoBoxNonceBytes() bytes of nonce.
* It must be preserved because it will be needed during decryption
* recipientPublicKey Recipient's public key for encrypting the message
* senderPrivateKey Sender's private key for creating authentication tag
*
* Returns:
* encrypted message as an array of bytes
*/
public static byte[] cryptoBoxEasy(byte[] message,
byte[] nonce
byte[] recipientPublicKey, byte[] senderPrivateKey) throws SodiumLibraryException
/**
* Bob (recipient) verifies the message with Alice's (sender) public key and
* decrypts the message with his private key
*
* Parameters:
* cipherText Message to decrypt
* nonce Nonce used during encryption
* senderPublicKey Sender's (Alice) public key for verifying message
* recipientPrivateKey Recipient's (Bob) Private key to decrypt the message
*
* Returns:
* Decrypted message as an array of bytes.
* In case of error SodiumLibraryException() run time exception will be thrown
*/
public static byte[] cryptoBoxOpenEasy(byte[] cipherText,
byte[]nonce,
byte[] senderPublicKey, byte[] recipientPrivateKey) throws SodiumLibraryException
/**
* Encrypts a message with recipient's public key.
*
* Usage: Alice can anonymously send a message to Bob by encrypting the message
* with his public key.
*
* Parameters:
* message The message bytes to encrypt
* recipientPublicKey Recipient's public key
*
* Rreturn:
* Encrypted message bytes. The length of the cipher text will be
* SodiumLibrary#cryptoBoxSealBytes() + message.length
*
* Tthrows SodiumLibraryException on error
*/
public static byte[] cryptoBoxSeal(byte[] message, byte[] recipientPublicKey)
throws SodiumLibraryException
/**
* Decrypts a ciphertext using recipient's key pair.
*
* Only the recipient can decrypt the message with his private key but the
* recipient can not identify the sender.
*
* Parameters:
* cipherText Ciphertext to decrypt
* pk Recipient's public key
* sk Recipient's private Key
*
* Returns:
* Decrypted plaintext bytes.
* @throws SodiumLibraryException on error
*/
public static byte[] cryptoBoxSealOpen(byte[] cipherText,byte[] pk, byte[] sk) throws SodiumLibraryException
- Alice generates her key pair
- Bob generate his key pair
- Alice (sender) Encrypts a message with Bob's (recipient) public key and creates authentication tag with her private key
- Bob (recipient) verifies the message with Alice's (sender) public key and decrypts with his private key
// Alice generates key pair
SodiumKeyPair aliceKeyPair = SodiumLibrary.cryptoBoxKeyPair();
byte[] alicePublicKey = aliceKeyPair.getPublicKey();
byte[] alicePrivateKey = aliceKeyPair.getPrivateKey();
// Bob generates key pair
SodiumKeyPair bobKeyPair = SodiumLibrary.cryptoBoxKeyPair();
byte[] bobPublicKey = bobKeyPair.getPublicKey();
byte[] bobPrivateKey = bobKeyPair.getPrivateKey();
// Generate nonce
// This API will be changed to return int in future version of libsodium-jna
byte[] nonce = SodiumLibrary.randomBytes(SodiumLibrary.cryptoBoxNonceBytes().intValue());
String secretMessage = "Hi Bob, This is Alice";
// Alice encrypts the message with Bob's public key, creates authentication tag
// with her private key
byte[] cipherText = SodiumLibrary.cryptoBoxEasy(
secretMessage.getBytes(), nonce,
bobPublicKey,
alicePrivateKey);
String cipherHex = SodiumUtils.binary2Hex(cipherText);
logger.info("Ciphertext: " + cipherHex);
// Bob Verifies with Alice's public key and decrypts ciphertext with his Private key
byte[] decrypted = SodiumLibrary.cryptoBoxOpenEasy(
cipherText, nonce,
alicePublicKey,
bobPrivateKey);
String decrypteString;
try
{
decrypteString = new String(decrypted, "UTF-8");
logger.info("decrypted: " + decrypteString);
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
// Bob generates key pair
SodiumKeyPair bobKeyPair = SodiumLibrary.cryptoBoxKeyPair();
byte[] bobPublicKey = bobKeyPair.getPublicKey();
byte[] bobPrivateKey = bobKeyPair.getPrivateKey();
String secretMessage = "Hi Bob, This is Alice";
// Alice encrypts with Bob's public key
byte[] cipherText = SodiumLibrary.cryptoBoxSeal(secretMessage.getBytes(), bobPublicKey);
String cipherHex = SodiumUtils.binary2Hex(cipherText);
logger.info("Ciphertext: " + cipherHex);
logger.info("Ciphertext length : " + cipherText.length);
long ciperTextlength = SodiumLibrary.cryptoBoxSealBytes() + secretMessage.length();
logger.info("length: " + ciperTextlength);
// Bob decrypts with his private key
byte[] decrypted = SodiumLibrary.cryptoBoxSealOpen(cipherText, bobPublicKey, bobPrivateKey);
try
{
String decrypteString = new String(decrypted, "UTF-8");
logger.info("decrypted: " + decrypteString);
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
From libsodium documentation:
Password hashing functions derive a secret key of any size from a password and a salt.
- The generated key has the size defined by the application, no matter what the password length is.
- The same password hashed with same parameters will always produce the same output.
- The same password hashed with different salts will produce different outputs.
- The function deriving a key from a password and a salt is CPU intensive and intentionally requires a fair amount of memory. Therefore, it mitigates brute-force attacks by requiring a significant effort to verify each password.
/**
* Derives a key from a password and the given salt using Argon2i
*
* Parameters:
* password The password
* salt The salt. The salt must be SodiumLibrary.cryptoPwhashSaltBytes() bytes long
*
* Comments:
* This method uses:
* opslimit as crypto_pwhash_opslimit_interactive()
* memlimit as crypto_pwhash_memlimit_interactive()
* algorithm as crypto_pwhash_alg_argon2id13() (default n libsodium v1.0.15)
*
* Returns:
* The derived key as array of bytes.
* In case of error SodiumLibraryException() run time exception will be thrown
*/
public static byte[] cryptoPwhashArgon2i(byte[] passwd, byte[] salt) throws SodiumLibraryException
Make sure to Load the libsodium C Library first
String passPhrase = "This is a passphrase";
byte[] salt = SodiumLibrary.randomBytes(SodiumLibrary.cryptoPwhashSaltBytes());
String hex = SodiumUtils.binary2Hex(salt);
// create salt for deriving key from the pass phrase
// salt is public but needs to be saved
logger.info("Generated " + salt.length + " bytes of salt");
logger.info(hex);
logger.info("Derive key from passphrase");
byte[] key = SodiumLibrary.cryptoPwhashArgon2i(passPhrase.getBytes(), salt);
logger.info("Derived " + key.length + " bytes long key");
hex = SodiumUtils.binary2Hex(key);
logger.info(hex);
// Later when you need to derive the key from the passphrase, use the saved salt
/**
* Returns a US-ASCII encoded key derived from the password. The key can be stored for
* verification.
*
* Parameters:
* password The password
*
* Comments:
* Memory-hard, CPU-intensive hash function is applied to the
* password in key generation process.
*
* Automatically generated salt is used in the key generation
*
* Uses opslimit as crypto_pwhash_opslimit_interactive()
* Uses memlimit as crypto_pwhash_memlimit_interactive()
*
* Returns:
* derived key as US-ASCII encoded string
*/
public static String cryptoPwhashStr(byte[] password) throws SodiumLibraryException
Make sure to Load the libsodium C Library first
String password = new String("বাংলা");
// convert to UTF-8 encoded bytes
byte[] passwordBytes = password.getBytes(StandardCharsets.UTF_8); // requires jdk 1.7+
String key = SodiumLibrary.cryptoPwhashStr(passwordBytes);
/**
* Verify a US-ASCII encoded key derived previously by calling
* cryptoPwhashStr()
*
* Parameters:
* key US-ASCII encoded key to verify
* password The password
*
* Returns:
* true if the key can be verified, false otherwise
*/
public static boolean cryptoPwhashStrVerify(String usAsciiKey,
byte[] password)
Make sure to Load the libsodium C Library first
String password = new String("বাংলা");
// convert to UTF-8 encoded bytes
byte[] passwordBytes = password.getBytes(StandardCharsets.UTF_8); // requires jdk 1.7+
String key = SodiumLibrary.cryptoPwhashStr(passwordBytes);
// verify the password
boolean rc = SodiumLibrary.cryptoPwhashStrVerify(key, passwordBytes);
if (rc)
{
logger.info("Password is verified");
}
This instruction is for encrypting something with a symmetric memory hardened key derived from a passphrase and use that key in encryption. I am giving the example on encrypting a private key as this is a very common requirement.
When the public and private key pair is generated and if it is required to store the private key, the private key must be properly encrypted and stored. The following procedure can be used to encrypt the private key:
-
Come up with a strong pass phrase. Use a long memorable pass phrase. This is the most important defense against brute force cracking.
-
Generate cryptoPwhashSaltBytes() long salt
byte[] salt = SodiumLibrary.randomBytes(SodiumLibrary.cryptoPwhashSaltBytes);
- Derive a brute force resistant key from the pass phrase
byte[] key = SodiumLibrary.cryptoPwhashArgon2i(passPhrase, salt);
-
Store the salt. This will be used to derive the same key again from the pass phrase
-
Generate cryptoSecretBoxNonceBytes() long nonce
byte[] nonce = SodiumLibrary.randomBytes(SodiumLibrary.cryptoSecretBoxNonceBytes().intValue());
- Encrypt the private key
byte[] encryptedPrivateKey = SodiumLibrary.cryptoSecretBoxEasy(privateKey, nonce, key);
- Store nonce and the encrypted private key
- Derive the encryption key from the pass phrase and stored salt
byte[] key = SodiumLibrary.cryptoPwhashArgon2i(passPhraseBytes, saltBytes);
- Verify and decrypt the private key with the derived key and stored nonce
byte[] privateKey = SodiumLibrary.cryptoSecretBoxOpenEasy(encryptedPrivateKey, nonce, key);
License is MIT
Copyright © 2018-2024 muquit@muquit.com
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
If your project is not a maven project, find out the dependencies of libsodium-jna and obtain the jar files from maven central manually and add them to your build path
- find the dependencies
$ cd libsodium-jna
$ mvn dependency:tree
...
[INFO] ------------------------------------------------------------------------
[INFO] Building com.muquit.libsodiumjna 1.0.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ libsodium-jna ---
[INFO] com.muquit.libsodiumjna:libsodium-jna:jar:1.0.1
[INFO] +- net.java.dev.jna:jna:jar:4.2.2:compile
[INFO] +- org.slf4j:slf4j-api:jar:1.7.21:compile
[INFO] +- org.slf4j:slf4j-log4j12:jar:1.7.21:compile
[INFO] | \- log4j:log4j:jar:1.2.17:compile
[INFO] +- commons-codec:commons-codec:jar:1.10:compile
[INFO] \- junit:junit:jar:4.11:test
[INFO] \- org.hamcrest:hamcrest-core:jar:1.3:test
...
Created with markdown_helper with mkdocs.sh