libsodium-jni
libsodium-jni copied to clipboard
crypto_sign_verify_detached() return -1 when keys are not generated in the same method
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.
If you need to see code for this then here it is
- 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;
}
}
- 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);
}
}
- 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;
}
}
}
- 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;
}
}
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
Yes i have initialized NaCl.sodium() in the app start itself .
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.
Hello @joshjdevl , any update regarding this.