如何在 java 中获得与 nodejs 代码中相同的 base64 hmac?
How to get same base64 hmac in java as in nodejs code?
我正在尝试为 sha256 创建一个 base64 hmac。我有两个相同的代码,一个在 JS 中,另一个在 Java 中,尽管我在 android 中这样做,而 kotlin 代码也会帮助我。我只有 mos 只使用过来自其他 SO 答案的代码。 node js 中的那个似乎给出了正确的结果并与后端匹配,但在 java 中却没有。这是代码
const crypto = require('crypto')
const base64urlm = require('base64url')
console.log('hello')
var yourMessage = 'Pritish8-s9';
var sharedSecret = 'Nilesh/ev12/';
//generate hmac sha256 hash
var hmacSignature = crypto.createHmac('SHA256', new Buffer(sharedSecret, 'base64')).update(yourMessage).digest('base64');
hmacSignature = base64urlm.fromBase64(hmacSignature)
console.log(hmacSignature)
输出为
_eiq1peyHuPx8yQwzORwoT7wcNdzv2Y0LUp_E70aIvM
以上是正确的值。下面是 java 代码。
package com.drivertest.hmactest;
import android.util.Log;
import org.apache.commons.codec.binary.Hex;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class HMAC {
public static String cal() {
try {
String secret = "Nilesh/ev12/";
String message = "Pritish8-s9";
byte[] secretByteArray = new byte[0];
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
secretByteArray = Base64.getEncoder().encode(secret.getBytes());
}
//byte[] secretByteArray = Base64.encodeBase64(secret.getBytes("utf-8"), true);
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secretByteArray, "HmacSHA256");
sha256_HMAC.init(secret_key);
String hash = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
hash = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(message.getBytes()));
}
System.out.println("hash "+hash);
Log.d("++++",hash);
return hash;
}
catch (Exception e){
System.out.println("Error");
}
return "";
}
public static String encode(String key, String data) {
try {
String secret = "Nilesh/ev12/";
String message = "Pritish8-s9";
key=secret;
data=message;
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
sha256_HMAC.init(secret_key);
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secretKey);
String hash = android.util.Base64.encodeToString(sha256_HMAC.doFinal(message.getBytes()), android.util.Base64.DEFAULT);
Log.d("++",hash);
return Hex.encodeHexString(sha256_HMAC.doFinal(data.getBytes(StandardCharsets.UTF_8)));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
}
这是一个 class,我尝试以不同的方式与其他 SO 答案一起做。不幸的是我得到了一个像
这样的值
8i/ce0u0GZ+JhL3yblsGhaMnFC0UKkUwJSQSXZ3536s=
或
f22fdc7b4bb4199f8984bdf26e5b0685a327142d142a45302524125d9df9dfab
那么谁能帮我写 java/kotlin 相同的代码并在 nodejs 中获得与上面相同的值?
PS :我已经在随机站点上验证了 java 结果,它们似乎匹配,但我的 api 因该值而失败,并且只有在可以的情况下才能工作与那个 os nodejs 匹配,所以在这个意义上它是不正确的。
谢谢:)
您的 nodejs 和 Java 实现之间存在两个差异。
首先也是最重要的:在 nodejs 中,您使用 base64 解码 您的秘密,而在 Java 中,您 编码 它:
Base64.getEncoder().encode(secret.getBytes())
替换为:
Base64.getDecoder().decode(secret.getBytes())
其次,在 nodejs 中,您在对最终结果进行编码时使用 base64 (base64urlm
) 的 URL 变体。在 Java 中,您使用常规的 base64。将其替换为:
Base64.getUrlEncoder().encodeToString(...)
我正在尝试为 sha256 创建一个 base64 hmac。我有两个相同的代码,一个在 JS 中,另一个在 Java 中,尽管我在 android 中这样做,而 kotlin 代码也会帮助我。我只有 mos 只使用过来自其他 SO 答案的代码。 node js 中的那个似乎给出了正确的结果并与后端匹配,但在 java 中却没有。这是代码
const crypto = require('crypto')
const base64urlm = require('base64url')
console.log('hello')
var yourMessage = 'Pritish8-s9';
var sharedSecret = 'Nilesh/ev12/';
//generate hmac sha256 hash
var hmacSignature = crypto.createHmac('SHA256', new Buffer(sharedSecret, 'base64')).update(yourMessage).digest('base64');
hmacSignature = base64urlm.fromBase64(hmacSignature)
console.log(hmacSignature)
输出为
_eiq1peyHuPx8yQwzORwoT7wcNdzv2Y0LUp_E70aIvM
以上是正确的值。下面是 java 代码。
package com.drivertest.hmactest;
import android.util.Log;
import org.apache.commons.codec.binary.Hex;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class HMAC {
public static String cal() {
try {
String secret = "Nilesh/ev12/";
String message = "Pritish8-s9";
byte[] secretByteArray = new byte[0];
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
secretByteArray = Base64.getEncoder().encode(secret.getBytes());
}
//byte[] secretByteArray = Base64.encodeBase64(secret.getBytes("utf-8"), true);
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secretByteArray, "HmacSHA256");
sha256_HMAC.init(secret_key);
String hash = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
hash = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(message.getBytes()));
}
System.out.println("hash "+hash);
Log.d("++++",hash);
return hash;
}
catch (Exception e){
System.out.println("Error");
}
return "";
}
public static String encode(String key, String data) {
try {
String secret = "Nilesh/ev12/";
String message = "Pritish8-s9";
key=secret;
data=message;
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
sha256_HMAC.init(secret_key);
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secretKey);
String hash = android.util.Base64.encodeToString(sha256_HMAC.doFinal(message.getBytes()), android.util.Base64.DEFAULT);
Log.d("++",hash);
return Hex.encodeHexString(sha256_HMAC.doFinal(data.getBytes(StandardCharsets.UTF_8)));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
}
这是一个 class,我尝试以不同的方式与其他 SO 答案一起做。不幸的是我得到了一个像
这样的值8i/ce0u0GZ+JhL3yblsGhaMnFC0UKkUwJSQSXZ3536s=
或
f22fdc7b4bb4199f8984bdf26e5b0685a327142d142a45302524125d9df9dfab
那么谁能帮我写 java/kotlin 相同的代码并在 nodejs 中获得与上面相同的值?
PS :我已经在随机站点上验证了 java 结果,它们似乎匹配,但我的 api 因该值而失败,并且只有在可以的情况下才能工作与那个 os nodejs 匹配,所以在这个意义上它是不正确的。
谢谢:)
您的 nodejs 和 Java 实现之间存在两个差异。
首先也是最重要的:在 nodejs 中,您使用 base64 解码 您的秘密,而在 Java 中,您 编码 它:
Base64.getEncoder().encode(secret.getBytes())
替换为:
Base64.getDecoder().decode(secret.getBytes())
其次,在 nodejs 中,您在对最终结果进行编码时使用 base64 (base64urlm
) 的 URL 变体。在 Java 中,您使用常规的 base64。将其替换为:
Base64.getUrlEncoder().encodeToString(...)