对于blake2b哈希,这是一种功能性方法,我得到的结果不一致。在我看来,这个问题是在Java方面,它以某种方式对两个方法调用之间的输入参数进行了更改。我无法理解两次调用SodiumJNI.crypto_generichash_blake2b_salt_personal_no_input
之间的输入参数是怎么回事。本机函数(如下所示)不会对key
,salt
和info
进行任何更改。因此,输出应相同,但不相同。
我的测试方法如下:
import android.util.Base64;
import android.util.Log;
static void kdf() {
final byte[] key = new byte[32];
final byte[] salt = new byte[32];
final byte[] info = Base64.decode("aGFuZHNoYWtl", Base64.DEFAULT);
byte[] out0 = new byte[64];
int result0 = SodiumJNI.crypto_generichash_blake2b_salt_personal_no_input(out0, out0.length, key, key.length, salt, info);
if (result0 == 0) {
Log.d("Tests", "out0: " + Base64.encodeToString(out0, Base64.DEFAULT));
//prints:
//out0: nCzeDcbw1YmdPq+jYnslNDoXKNyXMvIsqx9QJ1PLRNPxh7dvXkTeSkF2REYznHExaWCQP7J0kFvDu9l9ECs4VQ==
}
byte[] out1 = new byte[64];
int result1 = SodiumJNI.crypto_generichash_blake2b_salt_personal_no_input(out1, out1.length, key, key.length, salt, info);
if (result1 == 0) {
Log.d("Tests", "out1: " + Base64.encodeToString(out1, Base64.DEFAULT));
//prints;
//out1: dNfj+ccfGzTDiTAgzHNE5Hujyxnl6yX2BAPamCBw8X3fPYgbdtNDPoA3JKQGCziJw40wVTr/kPCpVUqMqMiVKw==
}
}
现在奇怪的是,out0
和out1
并不相同。
本机函数实现如下:
public class SodiumJNI {
public final static native int sodium_init();
public final static native int crypto_generichash_blake2b_salt_personal_no_input(byte[] out, int outlen, byte [] key, int keylen, byte[] salt, byte[] personal);
static {
try {
System.loadLibrary("sodiumjni");
if (sodium_init() == -1) {
throw new RuntimeException("Sodium could not be initialized.");
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
本机函数:
JNIEXPORT jint JNICALL Java_com_app_jni_SodiumJNI_crypto_1generichash_1blake2b_1salt_1personal_1no_1input(JNIEnv *jenv, jclass jcls,
jbyteArray joutput, jint joutlength, jbyteArray jkey, jint jkeylength, jbyteArray jsalt, jbyteArray jpersonal) {
jint jresult = 0 ;
unsigned char *output = (unsigned char *) 0 ;
size_t outlength ;
unsigned char *key = (unsigned char *) 0 ;
size_t keylength ;
unsigned char *salt = (unsigned char *) 0 ;
unsigned char *personal = (unsigned char *) 0 ;
int result;
(void)jenv;
(void)jcls;
{
output = (unsigned char *) (*jenv)->GetByteArrayElements(jenv, joutput, 0);
}
outlength = (size_t)joutlength;
{
key = (unsigned char *) (*jenv)->GetByteArrayElements(jenv, jkey, 0);
}
keylength = (size_t)jkeylength;
{
salt = (unsigned char *) (*jenv)->GetByteArrayElements(jenv, jsalt, 0);
}
{
personal = (unsigned char *) (*jenv)->GetByteArrayElements(jenv, jpersonal, 0);
}
result = (int)crypto_generichash_blake2b_salt_personal(output,
outlength,
NULL,
0,
(unsigned char const *)key,
keylength,
(unsigned char const *)salt,
(unsigned char const *)personal);
jresult = (jint)result;
{
(*jenv)->ReleaseByteArrayElements(jenv, joutput, (jbyte *) output, 0);
}
{
(*jenv)->ReleaseByteArrayElements(jenv, jkey, (jbyte *) key, JNI_ABORT);
}
{
(*jenv)->ReleaseByteArrayElements(jenv, jsalt, (jbyte *) salt, JNI_ABORT);
}
{
(*jenv)->ReleaseByteArrayElements(jenv, jpersonal, (jbyte *) personal, JNI_ABORT);
}
return jresult;
}