Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto_sign_verify_detached() return -1 when keys are not generated in the same method #137

Open
shaggi7 opened this issue Jan 17, 2020 · 5 comments

Comments

@shaggi7
Copy link

shaggi7 commented Jan 17, 2020

Hi,
@joshjdevl
I am making a encryption library using libsodium jni .
This is my method

 public void test(){
        int ret=0;

        long publickeylen = Sodium.crypto_sign_publickeybytes();
        long privatekeylen = Sodium.crypto_sign_secretkeybytes();

        final byte[] public_key = new byte[(int)publickeylen];
        final byte[] private_key = new byte[(int)privatekeylen];

        Sodium.randombytes(public_key,(int)publickeylen);
        Sodium.randombytes(private_key,(int)privatekeylen);

        ret = Sodium.crypto_sign_keypair(public_key,private_key);
        long signatureLength = Sodium.crypto_sign_bytes();
        byte [] message = "test".getBytes();
        byte[] signatureBytes =  new byte[(int)signatureLength];
        final int[] signed_message_len = new int[1];
        final int[] message_len = new int[1];
        int ret2=Sodium.crypto_sign_detached(signatureBytes,signed_message_len,message,message.length,private_key);
        System.out.println("length of signature: "+signatureBytes.length);

        int message_len2 = 0 ;
        int isValid = Sodium.crypto_sign_verify_detached(signatureBytes, message, message.length, public_key);
        System.out.println("verification result in test: "+isValid);

    }

Although this method is verifying signature correctly but i am making seperate classes for PublicKeys, PrivateKey, Signature, KeyPair. And when i uses keys from these classess the verification always fails even i have manually verified that the keys are same at the time of creation, signing and verification. What can be the issue.

@shaggi7
Copy link
Author

shaggi7 commented Jan 17, 2020

If you need to see code for this then here it is

  1. Keys.java
import org.libsodium.jni.Sodium;
import org.libsodium.jni.SodiumJNI;

public class Keys {

    PublicKey publicKey;
    PrivateKey privateKey;

    public Keys(){

        int ret=0;
        utils util = new utils();

        long publickeylen = Sodium.crypto_sign_publickeybytes();
        long privatekeylen = Sodium.crypto_sign_secretkeybytes();

        final byte[] public_key = new byte[(int)publickeylen];
        final byte[] private_key = new byte[(int)privatekeylen];

        Sodium.randombytes(public_key,(int)publickeylen);
        Sodium.randombytes(private_key,(int)privatekeylen);

        ret = Sodium.crypto_sign_keypair(public_key,private_key);

        byte[] epk = new byte[(int)publickeylen];
        byte[] esk = new byte[(int)privatekeylen];
        ret = SodiumJNI.crypto_sign_ed25519_pk_to_curve25519(public_key, epk);
        ret = SodiumJNI.crypto_sign_ed25519_sk_to_curve25519(private_key, esk);
        util.printByteArray("Public key while generation: ",public_key);
        util.printByteArray("Private key while generation: ",private_key);
        this.publicKey = new PublicKey(public_key, epk);
        this.privateKey = new PrivateKey(private_key, esk);
    }

    public PrivateKey getPrivateKey() {
        return this.privateKey;
    }

    public PublicKey getPublicKey() {
        return this.publicKey;
    }
}

  1. PublicKeys.java
import android.util.Base64;
import android.util.Log;

import com.protocol.tntproto.internals.Exceptions.InvalidLengthException;

import org.libsodium.jni.Sodium;
import org.libsodium.jni.SodiumJNI;

public class PublicKey {

    private static final String LOGTAG = "PUBLIC KEYS: ";
    private byte[] publicEdwardBytes = new byte[(int) Sodium.crypto_sign_publickeybytes()];
    private byte[] publicCurveBytes = new byte[(int) Sodium.crypto_sign_secretkeybytes()];
    public String publicEdward = null;
    public String publicCurve = null;

    public PublicKey(){
        Log.d(LOGTAG, "Empty public key");
    }

    public PublicKey(byte[] pk, byte[] epk){
        this.publicEdwardBytes = pk;
        this.publicCurveBytes = epk;
        this.encode();
    }

    public String getPublicEdward(){
        return this.publicEdward;
    }

    public String getPublicCurve(){
        return this.publicCurve;
    }

    private void encode(){
        this.publicEdward  = Base64.encodeToString(this.publicEdwardBytes,Base64.DEFAULT);
        this.publicCurve = Base64.encodeToString(this.publicCurveBytes, Base64.DEFAULT);
    }

    private void decode(){
        try {
            this.publicEdwardBytes = this.publicEdward.getBytes();
            this.publicCurveBytes = this.publicCurve.getBytes();
        }
        catch(NullPointerException e){
            System.out.print("public Key are null");
            throw e;
        }
    }

    public void verify(String messageString, Signature signature){
        System.out.println("Verifying your message!!!!!!!!!!!!!!!");
        try{
            byte [] message = messageString.getBytes();
            utils util = new utils();
            int len = message.length;
            final int[] message_len = new int[1] ;
            util.printByteArray("Public key while vrifying: ",this.publicEdwardBytes);
            util.printByteArray("Signature while verifying", signature.getSignatureBytes());
            int isValid = Sodium.crypto_sign_verify_detached(signature.getSignatureBytes(), message, message.length, this.publicEdwardBytes);
            System.out.println("verification result "+isValid);
        }
        catch(NullPointerException e){
            System.out.println(e.getMessage());
        }
    }

    public void test(){
        int ret=0;

        long publickeylen = Sodium.crypto_sign_publickeybytes();
        long privatekeylen = Sodium.crypto_sign_secretkeybytes();

        final byte[] public_key = new byte[(int)publickeylen];
        final byte[] private_key = new byte[(int)privatekeylen];

        Sodium.randombytes(public_key,(int)publickeylen);
        Sodium.randombytes(private_key,(int)privatekeylen);

        ret = Sodium.crypto_sign_keypair(public_key,private_key);
        long signatureLength = Sodium.crypto_sign_bytes();
        byte [] message = "test".getBytes();
        byte[] signatureBytes =  new byte[(int)signatureLength];
        final int[] signed_message_len = new int[1];
        final int[] message_len = new int[1];
        int ret2=Sodium.crypto_sign_detached(signatureBytes,signed_message_len,message,message.length,private_key);
        System.out.println("length of signature: "+signatureBytes.length);

        int message_len2 = 0 ;
        int isValid = Sodium.crypto_sign_verify_detached(signatureBytes, message, message.length, public_key);
        System.out.println("verification result in test: "+isValid);

    }
}

  1. PrivateKeys.java
package com.protocol.tntproto.internals;

import android.util.Base64;
import android.util.Log;

import org.libsodium.jni.Sodium;

public class PrivateKey {

    private static final String LOGTAG = "PUBLIC KEYS: ";
    private byte[] privateEdwardBytes = new byte[(int) Sodium.crypto_sign_secretkeybytes()];
    private byte[] privateCurveBytes = new byte[(int) Sodium.crypto_sign_secretkeybytes()];
    public String privateEdward = null;
    public String privateCurve = null;

    public PrivateKey(){
        Log.d(LOGTAG,"Empty private key created");
    }

    public PrivateKey(byte[] sk,  byte[] esk){
        utils util = new utils();
        util.printByteArray("Private key while creating PrivateKey: ", sk);
        this.privateEdwardBytes = sk;
        this.privateCurveBytes = esk;
        this.encode();
    }

    public String getPrivateEdward(){
        return this.privateEdward;
    }

    public String getPrivateCurve(){
        return this.privateCurve;
    }

    public Signature sign(String message){
        byte[] messageBytes = message.getBytes();
        Signature sig = new Signature(this.privateEdwardBytes, messageBytes);
        utils util = new utils();
        util.printByteArray("Private key while vrifying: ",this.privateEdwardBytes);
        return sig;
    }

    private void encode(){
        this.privateEdward  = Base64.encodeToString(this.privateEdwardBytes,Base64.DEFAULT);
        this.privateCurve   = Base64.encodeToString(this.privateCurveBytes, Base64.DEFAULT);
    }

    private void decode(){
        try {
            this.privateEdwardBytes = this.privateEdward.getBytes();
            this.privateCurveBytes = this.privateCurve.getBytes();
        }
        catch(NullPointerException e){
            System.out.print("Private Keys are Null");
            throw e;
        }
    }

}

  1. Signature.java
import android.util.Base64;
import android.util.Log;

import org.libsodium.jni.NaCl;
import org.libsodium.jni.Sodium;
import org.libsodium.jni.SodiumJNI;

public class Signature {
    private static final String LOGTAG = "SIGNATURE: ";
    long signatureLength = Sodium.crypto_sign_bytes();
    byte[] signatureBytes =  new byte[(int)signatureLength];
    String signature = null;
//    public Signature()

    public String getSignature(){
        return this.signature;
    }

    public byte[] getSignatureBytes() {
        return this.signatureBytes;
    }

    public Signature(byte[] sk, byte[] message){

        final int[] signed_message_len = new int[1];
        final int[] message_len = new int[1];
        int ret=Sodium.crypto_sign_detached(this.signatureBytes,signed_message_len,message,message.length,sk);
        utils util = new utils();
        util.printByteArray("private byte while creating signature: ",sk);
        util.printByteArray("Signature created: ",this.signatureBytes);
        this.encode();
    }

    private void encode(){
        this.signature = Base64.encodeToString(this.signatureBytes,Base64.DEFAULT);
        return;
    }

    private void decode(){
        this.signatureBytes = this.signature.getBytes();
        return;
    }

}

@joshjdevl
Copy link
Owner

Have you tried initialization?

import org.libsodium.jni.NaCl; (this calls System.loadLibrary("sodiumjni");)
call NaCl.sodium().

https://github.com/joshjdevl/libsodium-jni#usage

https://github.com/joshjdevl/libsodium-jni/blob/master/src/test/java/org/libsodium/jni/publickey/SignatureTest.java

@shaggi7
Copy link
Author

shaggi7 commented Feb 10, 2020

Yes i have initialized NaCl.sodium() in the app start itself .

@janekp
Copy link

janekp commented Feb 16, 2020

I have the same issue. It returns -1

I also tried sodium_crypto_sign_verify_detached() in PHP and that fails too. A signature generated in PHP works fine.

@shaggi7
Copy link
Author

shaggi7 commented Feb 24, 2020

Hello @joshjdevl ,
any update regarding this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants