TweetNaCl in Java - a port of TweetNaCl-js

Overview

TweetNacl in Java: port of tweetnacl-js

Java CI

API/Usage

Suggest always use TweetNaclFast implementation

Public key authenticated encryption

  • get key pair: Box.KeyPair kp = Box.keyPair(), kp = Box.keyPair_fromSecretKey(sk)
  • new Box object: Box box = new Box(theirPublicKey, mySecretKey, Nonce);
  • encryption: cipher = box.box(message);
  • decryption: message = box.open(cipher);
  • Nonce MUST be unique for ever message passed between same peers

As an alternative, the nonce can be omitted from the Box() call, and passed in the box and open calls, like:

  • byte [] nonce = new byte[nonceLength], randombytes(theNonce, nonceLength);
  • Box.KeyPair kp = Box.keyPair(), kp = Box.keyPair_fromSecretKey(sk)
  • Box box = new Box(theirPublicKey, mySecretKey);
  • encryption: cipher = box.box(message, nonce);
  • decryption: message = box.open(cipher, nonce);

Secret key authenticated encryption

  • get shared key: crypto random, what you have
  • new SecretBox object: SecretBox sbox = new SecretBox(sharedKey, Nonce);
  • encryption: cipher = sbox.box(message);
  • decryption: message = sbox.open(cipher);
  • Nonce MUST be unique for ever message passed between same peers

As an alternative, the nonce can be omitted from the SecretBox() call, and passed in the box and open calls, like:

  • byte [] nonce = new byte[nonceLength], randombytes(theNonce, nonceLength);
  • SecretBox sbox = new SecretBox(sharedKey);
  • cipher = sbox.box(message, nonce);
  • decryption: message = sbox.open(cipher, nonce);

Signature

  • get key pair: Signature.KeyPair kp = Signature.keyPair(), kp = Signature.keyPair_fromSecretKey(sk);
  • new Signature object: Signature sig = new Signature(theirPublicKey, mySecretKey);
  • sign: signedMessage = sig.sign(message);
  • verify: message = sig.open(signedMessage);
  • Nonce MUST be unique for ever message passed between same peers

Hash

  • generate SHA-512: byte [] tag = Hash.sha512(message);

Refer to com.iwebpp.crypto.tests for details

About Random generation

  • the library uses java.security.SecureRandom for key generation
  • you can always use the library to generate key, or use a Crypto Random like java.security.SecureRandom

Testing

In top directory:

$ mvn test

Support us

  • Welcome contributing on document, codes, tests and issues

License MIT

Comments
  • Compatibility between TweetNacl and TweetNaclFast for Box?

    Compatibility between TweetNacl and TweetNaclFast for Box?

    As I understand it, the "Fast" version pre-calculates the DH shared-key and uses that directly for the encryption&signing. I expected the output from the box() method on the TweetNacl.Box and the TweetNaclFast.Box instances to be compatible, i.e. have the same encrypted message and format, and be interchangeable.

    However, I get errors if I mix them up, like in TweetNaclFastTest.java, I added

               import com.iwebpp.crypto.TweetNacl;
    

    and added to the Box test case:

        // peer A -> B
        TweetNaclFast.Box pab = new TweetNaclFast.Box(kb.getPublicKey(), ka.getSecretKey());
        //TweetNacl.Box pab = new TweetNacl.Box(kb.getPublicKey(), ka.getSecretKey());
    
        // peer B -> A
        TweetNaclFast.Box pba = new TweetNaclFast.Box(ka.getPublicKey(), kb.getSecretKey());
        //TweetNacl.Box pba = new TweetNacl.Box(ka.getPublicKey(), kb.getSecretKey());
    

    If they are compatible, I can mix and match the two classes - uncomment one and comment the other. However, I get null pointers when I do that. All ok when I box() and open() with the same version.

    Is that a bug? Do I miss anything?

    opened by franks42 9
  • Use of nonce in class Box is unclear

    Use of nonce in class Box is unclear

    Trying to understand how that nonce is used in the "Box" class code, and I'm "puzzled".

    As I understand the use of the nonce, Alice has to generate that unique nonce that is used inside Box's "box" method in the "crypto_box" call, and that same non-secret nonce has to be communicated to Bob, who will use it inside of Box's "open" method to decrypt in the "crypto_box_open" call. The nonce is used in addition to the shared secret or the private keys, and the difference is that it is not a secret and should be uniquely tied to the encrypted message.

    However, the only way to (optionally) pass a nonce in, is through the Box constructor, but there seems to be no way to get that nonce value out. How does Alice communicate the used nonce to Bob?

    Also, the nonce value passed-in is a java-long, which has to be converted to a byte[], which is tricky if you have to communicate values between different languages and CPUs. (the C-implementation seems to work with char arrays only (?), while the example code in bench.cpp prepares a nonce value that is passed to both the crypto_secretbox() and crypto_secretbox_open())

    If I compare it to the Kalium code, then the nonce is passed in the encrypt and decrypt methods of the Kalium's Box class explicitly (as byte[]), which seem to map to tweet-nacl-java's Box's "box" and "open" call.

    It's not easy to follow the correct flow in the code, and I may very well be missing something... but right now it feels to me that the nonce may be used incorrectly.

    opened by franks42 4
  • [BUG] A defect in function `crypto_sign_open`

    [BUG] A defect in function `crypto_sign_open`

    I used to invoke function crypto_sign_open which in TweetNacl.java and had never verified successfully. How I write a process is follows:

        TweetNacl.Signature signObj = new TweetNacl.Signature(Base58Utils.decode(pubKey), new byte[0]);
        return signObj.detached_verify(signMessage.getBytes(StandardCharsets.UTF_8), Base58Utils.decode(signature));
    

    Then i found that there is a bug in the function vn:

        private static int vn(
                byte [] x, final int xoff, final int xlen,
                byte [] y, final int yoff, final int ylen,
                int n)
        {
            int i,d = 0;
            for (i = 0; i < n; i ++) {
                d |= (x[i+xoff]^y[i+yoff]) & 0xff;
            }
            return (1 & ((d - 1) >>> 8)) - 1;
        }
    

    which should be modified to:

        private static int vn(
                byte [] x, final int xoff, final int xlen,
                byte [] y, final int yoff, final int ylen,
                int n)
        {
            byte[] d = new byte[1];
            for (int i = 0; i < n; i ++) d[0] |= (x[i+xoff]^y[i+yoff]);
            return (1 & ((d[0] - 1) >>> 8)) - 1;
        }
    
    opened by furyGo 3
  • keyPair_fromSeed() is insecure/misleading

    keyPair_fromSeed() is insecure/misleading

    public static KeyPair keyPair_fromSeed(byte [] seed) simply takes the seed and uses it as the secret key. This is horribly insecure, because seeds are usually of very little entropy and very predictable.

    Therefore, we should either rename the function to something like "keyPair_fromSecretKey(byte[] secretKey)",

    OR

    make it handle the seed correctly, for example by seeding SecureRandom with "seed" and then taking "sk" from it, like so:

    public static int crypto_box_keypair_with_seed(byte[] pk, byte[] sk, byte[] seed)
    {
        // create secret key randomly (default RNG of current platform)
        SecureRandom rng = new SecureRandom();
        byte[] random = new byte[crypto_secretbox_SECRETKEYBYTES];
        rng.nextBytes(random);
        
        // create more or less random number from seed
        SecureRandom rngSeeded = SecureRandom.getInstance("SHA1PRNG");
        rngSeeded.setSeed(seed);
        byte[] randomSeeded = new byte[crypto_secretbox_SECRETKEYBYTES];
        rngSeeded.nextBytes(randomSeeded);
    
        // XOR the two random numbers, forming the secret key
        for (byte b : random) {
            sk[i] = b ^ randomSeeded[i++];
        }
        
        return curve25519.crypto_scalarmult_base(pk, sk);
    } 
    

    PS: excuse me for taking this example from jNaCl.

    This actually creates "random" randomly (default PRNG), then seeds the SHA1-PRNG with "seed" and gets a second random number "randomSeeded", finally XORing "random" and "randomSeeded" together, to form "sk". This was done because the default PRNG is sometimes better than SHA1-PRNG, sometimes worse, but in any case should we never solely rely on a deterministic seeding of the SHA1-PRNG. SHA1 was chosen, however, because it is widely believed to be secure, IF the seed is not compromised. By combining both methods (via XOR), we hopefully get the best of both worlds.

    What do you think of this? Cheers

    opened by ryhaberecht 3
  • Randomly brings infinit loop

    Randomly brings infinit loop

    Hi ! I'm trying to bring a JS software to java using this lib and I don't know much about all the theory and crypto things it use.

    I quite often (1 over 2 try) run into infinite loop while calling: public static int crypto_secretbox(byte [] c, byte [] m, int /long/ d, byte [] n, byte [] k);

    When such infinit loop may occur ? Would a unit test showing the call with params and the infinit loop in action help ? Many thanks for your help

    opened by legarspol 3
  • Insecure PRNG

    Insecure PRNG

    tweetnacl-java uses java.util.Random which is not a CPRNG and thus is not suitable for cryptographic applications because it can be easily predicted. java.security.SecureRandom is CPRNG that is generally available on JVMs.

    opened by ott 3
  • running the tests

    running the tests "easily"

    Hi Tom - thanks for the tweetnacl port - great work!!!

    Not sure how you run the java tests in TweetNaclTest and TweetNaclFastTest... I've added to TweetNaclTest.java:

    public static void main(String[] args) {
        TweetNaclTest t = new TweetNaclTest();
        t.start();
    }
    

    and similar lines to the TweetNaclFastTest.java.

    Then run the following from the command line in top directory:

    $ mkdir out $ javac -d out src/com/iwebpp/crypto/TweetNacl.java src/com/iwebpp/crypto/TweetNaclFast.java src/com/iwebpp/crypto/tests/TweetNaclTest.java src/com/iwebpp/crypto/tests/TweetNaclFastTest.java src/com/iwebpp/crypto/tests/Log.java $ java -cp out com.iwebpp.crypto.tests.TweetNaclTest $ java -cp out com.iwebpp.crypto.tests.TweetNaclFastTest

    Want to add those few lines to the TweetNaclTest.java, TweetNaclFastTest.java and the readme?

    opened by franks42 2
  • Failed to resolve: io.github.instantwebp2p:tweetnacl-java:1.1.2

    Failed to resolve: io.github.instantwebp2p:tweetnacl-java:1.1.2

    Trying to include tweetnacl-java:1.1.2 in my project, and I have got this error. Please help

    "Failed to resolve: io.github.instantwebp2p:tweetnacl-java:1.1.2"

    opened by here-nerd 1
  • Could you create a new tag?

    Could you create a new tag?

    Would it be possible to throw a 1.1.2 tag at the current master?

    I'd like to use a tagged implementation, but 1.1.1 was from 2015, and it looks like there have been commits since then.

    opened by gconnell 1
  • Added a testBoxKalium() to TweetNaclFast.java that uses the test vect…

    Added a testBoxKalium() to TweetNaclFast.java that uses the test vect…

    …ors of the Kalium project (https://github.com/abstractj/kalium) for the Box::box&open.

    That should ensure that the implementation is correct and compatible with other sodium ports.

    Just want to focus on the "fast" implementation right now, so those test are only for the TweetNaclFast code.

    Also added a .ignore file to git-ignore the generated "out/*" files during testing.

    opened by franks42 1
  • In TweetNacl.java, added additional methods for Box' box, open, after…

    In TweetNacl.java, added additional methods for Box' box, open, after…

    …, and open_after, and for SecretBox' box and open, that pass an explicit byte[] nonce value to provide better interop with the other Nacl implementations.

    Added test cases to TweetNaclTest.java that use the explicit passing of a nonce byte[] value.

    Changes should be "upwards compatible" as old interfaces are still there and old tests still work.

    Note, the TweetNaclFast implementation has not been modified (yet) - need little more testing and feedback(?).

    opened by franks42 1
Releases(v1.1.2)
Owner
AppNet.Link
Secure P2P Virtual Network Gateway for IoT, Edge and Cloud Applications
AppNet.Link
enjarify 8.6 0.0 L5 Python Enjarify is a tool for translating Dalvik bytecode to equivalent Java bytecode. This allows Java analysis tools to analyze Android applications.

Note: This repository may be out of date. Future development will occur at https://github.com/Storyyeller/enjarify. Introduction Enjarify is a tool fo

Google 2.7k Jan 8, 2023
CLI tool for decompiling Android apps to Java. It does resources! It does Java! Its real easy!

Easy-as-pie Android Decompiler Why One stop shop I got pretty tired of decompiling Android apps with a bunch of steps that I had to remember all the t

Alex Davis 619 Dec 27, 2022
Signal Protocol library for Java/Android

Overview A ratcheting forward secrecy protocol that works in synchronous and asynchronous messaging environments. PreKeys This protocol uses a concept

Signal 1.8k Dec 24, 2022
Grab’n Run, a simple and effective Java Library for Android projects to secure dynamic code loading.

Grab’n Run, a simple and effective Java Library for Android projects to secure dynamic code loading.

Luca Falsina 418 Dec 29, 2022
Dex to Java decompiler

JADX jadx - Dex to Java decompiler Command line and GUI tools for producing Java source code from Android Dex and Apk files Main features: decompile D

null 32.8k Jan 2, 2023
Analyze any Android/Java based app or game

ClassyShark Introduction ClassyShark is a standalone binary inspection tool for Android developers. It can reliably browse any Android executable and

Google 7.2k Jan 3, 2023
A Java ePub reader and parser framework for Android.

FolioReader-Android is an EPUB reader written in Java and Kotlin. Features Custom Fonts Custom Text Size Themes / Day mode / Night mode Text Highlight

FolioReader 2.1k Jan 3, 2023
A program analysis tool to find cryptographic misuse in Java and Android.

A program analysis tool to find cryptographic misuse in Java and Android.

null 92 Dec 15, 2022
CRYLOGGER: Detecting Crypto Misuses for Android and Java Apps Dynamically

CRYLOGGER: Detecting Crypto Misuses for Android and Java Apps Dynamically

Luca Piccolboni 139 Dec 12, 2022
Java bytecode obfuscator created by x4e.

Binscure Java bytecode obfuscator created by x4e. Usage First, create a config file, (example config here). When you have a config file, run binscure

null 35 Nov 22, 2022
Appdbg - make it possible to run android dex file in original Java Virtual Machine

Appdbg - make it possible to run android dex file in original Java Virtual Machine

null 137 Dec 20, 2022
A RSA Cipher implementation for Kotlin/Java

A RSA Cipher implementation for Kotlin/Java.

Lyzev 3 Aug 22, 2022
Soot - A Java optimization framework

Using Soot? Let us know about it! We are regularly applying for funding to help us maintain Soot. You can help us immensely by letting us know about p

Soot Program Analysis Framework 2.5k Jan 2, 2023
Smali/baksmali is an assembler/disassembler for the dex format used by dalvik, Android's Java VM implementation

About smali/baksmali is an assembler/disassembler for the dex format used by dalvik, Android's Java VM implementation. The syntax is loosely based on

Ben Gruver 5.7k Dec 27, 2022
Find Security Bugs is the SpotBugs plugin for security audits of Java web applications

The SpotBugs plugin for security audits of Java web applications and Android applications. (Also work with Kotlin, Groovy and Scala projects)

OWASP Find Security Bugs 2k Jan 6, 2023
Catch common Java mistakes as compile-time errors

Error Prone Error Prone is a static analysis tool for Java that catches common programming mistakes at compile-time. public class ShortSet { public

Google 6.3k Dec 23, 2022
a 2d Java physics engine, native java port of the C++ physics engines Box2D and LiquidFun

jbox2d Please see the project's BountySource page to vote on issues that matter to you. Commenting/voting on issues helps me prioritize the small amou

jbox2d 1k Jan 2, 2023
Freegemas libGDX is an Android and Java desktop port of Freegemas, which in turn is an open source version of the well known Bejeweled.

freegemas-gdx Freegemas libGDX is an Android, HTML 5 and Java desktop port of Freegemas, which in turn is an open source version of the well known Bej

David Saltares 144 Jun 21, 2022
Freegemas libGDX is an Android and Java desktop port of Freegemas, which in turn is an open source version of the well known Bejeweled.

freegemas-gdx Freegemas libGDX is an Android, HTML 5 and Java desktop port of Freegemas, which in turn is an open source version of the well known Bej

David Saltares 144 Jun 21, 2022
Notify users when a new version of your Android app is available, and prompt them with the Play Store link. A port of the iOS library of the same name.

Siren for Android Notify users when a new version of your Android app is available, and prompt them with the Play Store link. This is a port of the iO

Quality Mobile Puzzle Apps 133 Nov 22, 2022