The
following Github repository has a JNI build of libsodium that can be added to
an Android project: https://github.com/joshjdevl/libsodium-jni
Scroll to
the bottom of the page where you will find the Android Archive (AAR) details:
From this,
you will need to create the following string:
com.github.joshjdevl.libsodiumjni:libsodium-jni-aar:1.0.8
We will
need this string later, so Android Studio can pull the AAR from Maven.
First of all,
enable Maven for your project. In Project Exlorer open your project’s
build.gradle file. You will find “repositories” near the top, add the following
line between the curly brackets:
mavenCentral()
The “repositories”
item will now look similar to this:
repositories {
google()
jcenter()
mavenCentral()
}
Maven is
now enabled, save and close the file.
Next, add
the libsodium AAR to your module’s dependencies. In Project Exlorer open your module’s
build.gradle file. Towards the bottom you will find “dependencies”. Remember
the string we constructed above, we will now add it to the list of dependencies
like so:
compile 'com.github.joshjdevl.libsodiumjni:libsodium-jni-aar:1.0.8'
The updates
dependencies will now look similar to this:
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support.constraint:constraint-layout:1.0.2' implementation 'com.android.support:design:26.1.0' testImplementation 'junit:junit:4.12' compile 'com.github.joshjdevl.libsodiumjni:libsodium-jni-aar:1.0.8' androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' }
Save and
close the file. Resync your project.
Finally, you need to change your AndroidManifest.xml. The reason for this is that the libsodium AAR has been built with a setting of allowBakckup: no, while your Android project wants to allow backups. You can decide whether you want no backups, or your project’s settings to override the libsodium settings.
To disallow backups for your project as well, locate the “
android:allowBackup="true"
to
android:allowBackup="false"
Instead, to
override libsodium settings and allow backups, again locate the “ ”
tag and add the following line inside the tag:
tools:replace="android:allowBackup"
In all likelihood
the “tools” namespace has not been declared yet, so add the following inside
the “ ” tag of the document:
xmlns:tools="http://schemas.android.com/tools"
That’s it.
Save and close again. Now you can use libsodium from your project.
Here is
some sample code; for more code examples your will have to look at unit test in
this Github project: https://github.com/joshjdevl/libsodium-jni
As the JNI version does not have all the high-level stuff that libsodium offers,
this is the best “documentation” I found.
Sodium sodium = NaCl.sodium(); long alice_publickeylen = Sodium.crypto_box_publickeybytes(); long alice_privatekeylen = Sodium.crypto_box_secretkeybytes(); byte[] alice_public_key = new byte[(int) alice_publickeylen]; byte[] alice_private_key = new byte[(int) alice_privatekeylen]; System.out.println("Generating keypair"); int ret = Sodium.crypto_box_keypair(alice_public_key, alice_private_key); Assert.assertEquals(0, ret); System.out.println(ret); System.out.println("Generated keyapir"); long bob_publickeylen = Sodium.crypto_box_publickeybytes(); long bob_privatekeylen = Sodium.crypto_box_secretkeybytes(); byte[] bob_public_key = new byte[(int) bob_publickeylen]; byte[] bob_private_key = new byte[(int) bob_privatekeylen]; System.out.println("Generating keypair"); ret = Sodium.crypto_box_keypair(bob_public_key, bob_private_key); Assert.assertEquals(0, ret); System.out.println(ret); System.out.println("Generated keyapir"); byte[] message = "test".getBytes(); long noncelen = Sodium.crypto_box_noncebytes(); byte[] nonce = new byte[(int) noncelen]; long ciphertextlen = Sodium.crypto_box_macbytes() + message.length; byte[] ciphertext = new byte[(int) ciphertextlen]; Sodium.randombytes_buf(nonce, (int) noncelen); ret = Sodium.crypto_box_easy(ciphertext, message, message.length, nonce, bob_public_key, alice_private_key); Assert.assertEquals(0, ret); byte[] decrypted = new byte[ciphertext.length - Sodium.crypto_box_macbytes()]; ret = Sodium.crypto_box_open_easy(decrypted, ciphertext, (int) ciphertext.length, nonce, alice_public_key, bob_private_key); Assert.assertEquals(0, ret); System.out.println("Recovered message=" + new String(decrypted));
Kudos to the people who maintain all the Github repositories involved here, from NaCl, which is the bases of Sodium, the creator of Sodium, Robosodium, which allows to create the JNI interface in an automated fashion, and not least the maintainer(s) of the AAR version, so not everyone has to go through the whole build process.
Closing note: If you are really paranoid, of course, (and you should be, if you work with cryptography), you should not trust any 3rd parties. You will need to pull the original source code and cross-compile it for all platforms yourself.
Closing note: If you are really paranoid, of course, (and you should be, if you work with cryptography), you should not trust any 3rd parties. You will need to pull the original source code and cross-compile it for all platforms yourself.