public class SodiumLibrary
extends java.lang.Object
SodiumLibraryException
at run time
in case of errors.
Please look at libsodium-jna Homepage for instructions on how to get started.
Modifier and Type | Class and Description |
---|---|
static interface |
SodiumLibrary.Sodium
Declare all the supported libsodium C functions in this interface and
implement them in this class as static methods.
|
Modifier and Type | Method and Description |
---|---|
static byte[] |
cryptoAuth(byte[] message,
byte[] key)
Computes an authentication tag for a message with a secret key.
|
static boolean |
cryptoAuthVerify(byte[] mac,
byte[] message,
byte[] key)
Verify message authentication code with the secret key
|
static byte[] |
cryptoBoxEasy(byte[] message,
byte[] nonce,
byte[] publicKey,
byte[] privateKey)
Encrypts a message with recipient's public key.
|
static SodiumKeyPair |
cryptoBoxKeyPair()
Randomly generates a private key and the corresponding public key
|
static NativeLong |
cryptoBoxMacBytes() |
static NativeLong |
cryptoBoxNonceBytes() |
static byte[] |
cryptoBoxOpenEasy(byte[] cipherText,
byte[] nonce,
byte[] publicKey,
byte[] privateKey)
Recipient decrypts a message with his private key.
|
static byte[] |
cryptoBoxSeal(byte[] message,
byte[] recipientPublicKey)
Encrypts a message with recipient's public key.
|
static NativeLong |
cryptoBoxSealBytes() |
static byte[] |
cryptoBoxSealOpen(byte[] cipherText,
byte[] pk,
byte[] sk)
Decrypts a ciphertext using recipient's key pair.
|
static byte[] |
cryptoGenerichash(byte[] input,
int length) |
static int |
cryptoNumberSaltBytes() |
static byte[] |
cryptoPublicKey(byte[] privateKey)
Given a private key, generate the corresponding public key
|
static byte[] |
cryptoPwhash(byte[] passwd,
byte[] salt,
long opsLimit,
NativeLong memLimit,
int algorithm) |
static int |
cryptoPwhashAlgArgon2i13() |
static int |
cryptoPwhashAlgArgon2id13() |
static int |
cryptoPwhashAlgDefault() |
static byte[] |
cryptoPwhashArgon2i(byte[] passwd,
byte[] salt)
Derive a key using Argon2id password hashing scheme
|
static NativeLong |
cryptoPwHashMemLimitInterative() |
static long |
cryptoPwHashOpsLimitInteractive() |
static int |
cryptoPwhashSaltBytes() |
static byte[] |
cryptoPwhashScrypt(byte[] passwd,
byte[] salt)
Derive key from a password using scrypt.
|
static byte[] |
cryptoPwhashScryptSalsa208Sha256(byte[] passwd,
byte[] salt,
java.lang.Long opsLimit,
NativeLong memLimit) |
static NativeLong |
cryptoPwHashScryptSalsa208Sha256SaltBytes() |
static java.lang.String |
cryptoPwhashStr(byte[] password)
Returns a US-ASCII encoded key derived from the password.
|
static boolean |
cryptoPwhashStrVerify(java.lang.String usAsciiKey,
byte[] password)
Verify a US-ASCII encoded key derived previously by calling
cryptoPwhashStr(byte[]) |
static SodiumSecretBox |
cryptoSecretBoxDetached(byte[] message,
byte[] nonce,
byte[] key)
Encrypts a message with a key and a nonce to keep it confidential - detached mode.
|
static byte[] |
cryptoSecretBoxEasy(byte[] message,
byte[] nonce,
byte[] key)
Encrypts a message with a key and a nonce to keep it confidential.
|
static NativeLong |
cryptoSecretBoxKeyBytes() |
static NativeLong |
cryptoSecretBoxMacBytes() |
static NativeLong |
cryptoSecretBoxNonceBytes() |
static byte[] |
cryptoSecretBoxOpenDetached(SodiumSecretBox secretBox,
byte[] nonce,
byte[] key)
Verifies and decrypts a ciphertext - detached mode
|
static byte[] |
cryptoSecretBoxOpenEasy(byte[] cipherText,
byte[] nonce,
byte[] key)
Verifies and decrypts a ciphertext.
|
static byte[] |
cryptoSign(byte[] m,
byte[] sk) |
static byte[] |
cryptoSignDetached(byte[] msg,
byte[] sk) |
static byte[] |
cryptoSignEdPkTOcurvePk(byte[] edPK) |
static byte[] |
cryptoSignEdSkTOcurveSk(byte[] edSK) |
static SodiumKeyPair |
cryptoSignKeyPair() |
static byte[] |
cryptoSignOpen(byte[] sig,
byte[] pk) |
static boolean |
cryptoSignVerifyDetached(byte[] sig,
byte[] msg,
byte[] pk) |
static NativeLong |
crytoBoxPublicKeyBytes() |
static NativeLong |
crytoBoxSecretKeyBytes() |
static NativeLong |
crytoBoxSeedBytes() |
static byte[] |
deriveKey(byte[] passwd,
byte[] salt)
A helper function to call cryptoPwhashArgon2i()
|
static java.lang.String |
getLibaryPath() |
static java.lang.String |
libsodiumVersionString() |
static void |
log(java.lang.String msg) |
static byte[] |
randomBytes(int size)
Return unpredictable sequence of bytes.
|
static void |
setLibraryPath(java.lang.String libraryPath)
Set the absolute path of the libsodium shared library/DLL.
|
static SodiumLibrary.Sodium |
sodium() |
public static void log(java.lang.String msg)
public static void setLibraryPath(java.lang.String libraryPath)
This method must be called before calling any methods in libsodium-jna. Although JNA supports loading a shared library from path, libsodium-jna requires specifying the absolute path to make sure that the exact library is being loaded. For example, in Linux, it might be /usr/local/lib/libsodium.so, in Windows, it might be c:/libs/libsodium.dll, in MacOS, it might be /usr/local/lib/libsodium.dylib etc. The point is there is no ambiguity, I want to load the library I want, not one from somewhere in the path.
libraryPath
- The absolute path of the libsodium library.
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);
public static java.lang.String getLibaryPath()
public static SodiumLibrary.Sodium sodium()
Although libsodium seems to be thread safe now, the code is written sometime back and I don't have plan to remove it at this time.
java.lang.RuntimeException
- at run time if the libsodium library path
is not set by calling setLibraryPath(String)
public static byte[] cryptoSignOpen(byte[] sig, byte[] pk) throws SodiumLibraryException
SodiumLibraryException
public static byte[] cryptoSign(byte[] m, byte[] sk) throws SodiumLibraryException
SodiumLibraryException
public static boolean cryptoSignVerifyDetached(byte[] sig, byte[] msg, byte[] pk) throws SodiumLibraryException
SodiumLibraryException
public static byte[] cryptoSignDetached(byte[] msg, byte[] sk) throws SodiumLibraryException
SodiumLibraryException
public static SodiumKeyPair cryptoSignKeyPair() throws SodiumLibraryException
SodiumLibraryException
public static byte[] cryptoGenerichash(byte[] input, int length) throws SodiumLibraryException
SodiumLibraryException
public static byte[] cryptoSignEdSkTOcurveSk(byte[] edSK) throws SodiumLibraryException
SodiumLibraryException
public static byte[] cryptoSignEdPkTOcurvePk(byte[] edPK) throws SodiumLibraryException
SodiumLibraryException
public static java.lang.String libsodiumVersionString()
public static byte[] randomBytes(int size)
- 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.
size
- Number of random bytes to generate
// 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);
public static byte[] cryptoPwhash(byte[] passwd, byte[] salt, long opsLimit, NativeLong memLimit, int algorithm) throws SodiumLibraryException
SodiumLibraryException
public static byte[] cryptoPwhashArgon2i(byte[] passwd, byte[] salt) throws SodiumLibraryException
The following is taken from libsodium documentation:
Argon2 is optimized for the x86 architecture and exploits the cache and memory organization of the recent Intel and AMD processors. But its implementation remains portable and fast on other architectures. Argon2 has three variants: Argon2d, Argon2i and Argon2id. Argon2i uses data-independent memory access, which is preferred for password hashing and password-based key derivation. Argon2i also makes multiple passes over the memory to protect from tradeoff attacks. Argon2id combines both.
passwd
- Array of bytes of passwordsalt
- Salt to use in key generation. The salt should be unpredictable and can be generated by calling SodiumLibary.randomBytes(int)
The salt should be saved by the caller as it will be needed to derive the key again from the
password.SodiumLibraryException
- if libsodium's crypto_pwhash() does not return 0
crypto_pwhash()
in Password hashing
libsodium page. Argon2i v1.3 Algorithm.
String password = "This is a Secret";
salt = SodiumLibary.randomBytes(sodium().crypto_pwhash_saltbytes());
byte[] key = SodiumLibary.cryptoPwhashArgon2i(password.getBytes(),salt);
String keyHex = SodiumUtils.bin2hex(key);
public static byte[] deriveKey(byte[] passwd, byte[] salt) throws SodiumLibraryException
passwd
- Password bytessalt
- Salt bytesSodiumLibraryException
- on errorpublic static java.lang.String cryptoPwhashStr(byte[] password) throws SodiumLibraryException
crypto_pwhash_opslimit_interactive()
and memlimit as
crypto_pwhash_memlimit_interactive()
password
- The password
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);
SodiumLibraryException
- on errorpublic static boolean cryptoPwhashStrVerify(java.lang.String usAsciiKey, byte[] password)
cryptoPwhashStr(byte[])
usAsciiKey
- US-ASCII encoded key to verifypassword
- The password
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");
}
public static byte[] cryptoPwhashScrypt(byte[] passwd, byte[] salt) throws SodiumLibraryException
Excerpt from libsodium documentation:
Scrypt was also designed to make it costly to perform large-scale custom hardware attacks by requiring large amounts of memory.Even though its memory hardness can be significantly reduced at the cost of extra computations, this function remains an excellent choice today, provided that its parameters are properly chosen.
Scrypt is available in libsodium since version 0.5.0, which makes it a better choice than Argon2 if compatibility with older libsodium versions is a concern.
passwd
- Array of bytes of passwordsalt
- Salt to use in key generation. The salt should be
unpredictable and can be generated by calling randomBytes(int)
The salt should be saved by the caller as it will be needed to derive the key again from the
password.SodiumLibraryException
- on errorpublic static byte[] cryptoPwhashScryptSalsa208Sha256(byte[] passwd, byte[] salt, java.lang.Long opsLimit, NativeLong memLimit) throws SodiumLibraryException
SodiumLibraryException
public static byte[] cryptoSecretBoxEasy(byte[] message, byte[] nonce, byte[] key) throws SodiumLibraryException
message
- message bytes to encryptnonce
- nonce bytes. The nonce must be cryptoBoxNonceBytes()
bytes long and can be generated by
calling randomBytes(int)
key
- They key for encryptionSodiumLibraryException
- on errorpublic static byte[] cryptoSecretBoxOpenEasy(byte[] cipherText, byte[] nonce, byte[] key) throws SodiumLibraryException
cryptoSecretBoxEasy(byte[] message, byte[] nonce, byte[] key)
cipherText
- The ciphertext to decryptnonce
- The nonce used during encryptionkey
- The key used in encryptionSodiumLibraryException
- - if nonce size is incorrect or decryption fails
// don't forget to load the libsodium library first
String message = "This is a message";
// generate nonce
long nonceBytesLength = SodiumLibrary.cryptoSecretBoxNonceBytes();
byte[] nonceBytes = SodiumLibrary.randomBytes((int) nonceBytesLength);
byte[] messageBytes = message.getBytes();
// generate the encryption key
byte[] key = SodiumLibrary.randomBytes((int) SodiumLibrary.cryptoSecretBoxKeyBytes());
// 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();
}
public static SodiumSecretBox cryptoSecretBoxDetached(byte[] message, byte[] nonce, byte[] key) throws SodiumLibraryException
message
- The message bytes to encryptnonce
- The nonce to use in encryptionkey
- The key to encryptSodiumSecretBox
SodiumLibraryException
- on errorpublic static byte[] cryptoSecretBoxOpenDetached(SodiumSecretBox secretBox, byte[] nonce, byte[] key) throws SodiumLibraryException
secretBox
- SodiumSecretBox
used during encryptionnonce
- Nonce used in encryptionkey
- The key used in encryptionSodiumLibraryException
- on errorpublic static byte[] cryptoAuth(byte[] message, byte[] key) throws SodiumLibraryException
cryptoAuthVerify(byte[] mac, byte[] message, byte[] key)
verify that the message is created by her.message
- Computes the tag for this message byteskey
- The secret key. The key size must be crypto_auth_keybytes() longSodiumLibraryException
- on errorpublic static boolean cryptoAuthVerify(byte[] mac, byte[] message, byte[] key) throws SodiumLibraryException
mac
- Message authentication codemessage
- The messagekey
- The secret key used to create the authentication codeSodiumLibraryException
- on errorpublic static SodiumKeyPair cryptoBoxKeyPair() throws SodiumLibraryException
SodiumKeyPair
SodiumLibraryException
- on errorpublic static byte[] cryptoPublicKey(byte[] privateKey) throws SodiumLibraryException
privateKey
- The private keySodiumLibraryException
- on errorpublic static NativeLong cryptoBoxNonceBytes()
public static NativeLong crytoBoxSeedBytes()
public static NativeLong crytoBoxPublicKeyBytes()
public static NativeLong crytoBoxSecretKeyBytes()
public static NativeLong cryptoBoxMacBytes()
public static NativeLong cryptoBoxSealBytes()
public static NativeLong cryptoSecretBoxKeyBytes()
public static NativeLong cryptoSecretBoxNonceBytes()
public static NativeLong cryptoSecretBoxMacBytes()
public static int cryptoNumberSaltBytes()
public static int cryptoPwhashAlgArgon2i13()
public static int cryptoPwhashAlgArgon2id13()
public static int cryptoPwhashAlgDefault()
public static int cryptoPwhashSaltBytes()
public static long cryptoPwHashOpsLimitInteractive()
public static NativeLong cryptoPwHashMemLimitInterative()
public static NativeLong cryptoPwHashScryptSalsa208Sha256SaltBytes()
public static byte[] cryptoBoxEasy(byte[] message, byte[] nonce, byte[] publicKey, byte[] privateKey) throws SodiumLibraryException
message
- The message to encryptnonce
- cryptoBoxNonceBytes()
bytes of nonce. It must be preserved because it will be needed during decryptionpublicKey
- Recipient's public key for encrypting the messageprivateKey
- Sender's private key for creating authentication tagSodiumLibraryException
- on errorpublic static byte[] cryptoBoxOpenEasy(byte[] cipherText, byte[] nonce, byte[] publicKey, byte[] privateKey) throws SodiumLibraryException
cipherText
- Message to decryptnonce
- Nonce used during encryptionpublicKey
- Sender's (Alice) public key for verifying the messageprivateKey
- Recipient's (Bob) Private key to decrypt the messageSodiumLibraryException
- on errorpublic static byte[] cryptoBoxSeal(byte[] message, byte[] recipientPublicKey) throws SodiumLibraryException
message
- The message bytes to encryptrecipientPublicKey
- Recipient's public keycryptoBoxSealBytes()
+ message.lengthSodiumLibraryException
- on errorpublic static byte[] cryptoBoxSealOpen(byte[] cipherText, byte[] pk, byte[] sk) throws SodiumLibraryException
cipherText
- Ciphertext to decryptpk
- Recipient's public keysk
- Recipient's private KeySodiumLibraryException
- on errorSodiumLibraryException
- on error