#java #node.js #one-time-password #code-translation
Вопрос:
Я написал кусок кода в NodeJS, который кодирует секретную строку в ключ otp для использования в другом приложении. Теперь я хочу сделать то же самое на Java для нескольких применений.
Узлы:
const crypto = require("crypto");
const secret = "3f944b3fea81e35994f9";
const counter = getCounter(); // Value: 00000000033ea377
console.log("Counter:", typeof counter,"-", counter);
// Returns: Counter: string - 00000000033ea377
const hmac = crypto.createHmac("sha1", Buffer.from(secret, 'hex'));
const digest = hmac.update(Buffer.from(counter, 'hex')).digest();
console.log("Digest:", typeof digest,"-", digest);
console.log("Digest(Hex):", typeof digest.toString("hex"),"-", digest.toString("hex"));
// Returns: Digest: object - <Buffer fb 6b 67 d4 5f ed 05 e8 be 74 44 b4 f9 22 d4 14 5a d1 11 b1>
// Returns: Digest(Hex): string - fb6b67d45fed05e8be7444b4f922d4145ad111b1
// Final Value: fb6b67d45fed05e8be7444b4f922d4145ad111b1
Ява:
String secret = "3f944b3fea81e35994f9";
String counter = "00000000033ea377"; // Same value as in the nodejs code
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec key = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA1");
mac.init(key);
System.out.println(BaseEncoding.base16().lowerCase()
.encode(mac.doFinal(counter.getBytes(StandardCharsets.UTF_8))));
// BaseEncoding is the class from Google's Guava (My version: 31.0.1-jre)
// Final Value: bccd0b95617b90ff497491e5c554b5e2545f1a4b
В Java я не получаю то же значение, что и в NodeJS. Я уверен, что это должно быть как-то связано с кодировками из Buffer.from(var, "hex")
Потому что, если я изменю
const hmac = crypto.createHmac("sha1", Buffer.from(secret, 'hex'));
const digest = hmac.update(Buffer.from(counter, 'hex')).digest();
Для
const hmac = crypto.createHmac("sha1", Buffer.from(secret, 'utf8')); // Changed from "hex" to "utf8"
const digest = hmac.update(Buffer.from(counter, 'utf8')).digest(); // Changed from "hex" to "utf8"
Я получаю то же значение, что и в коде Java, но API, для которого я использую токен, теперь выдает ошибку о том, что токен недействителен. Я попытался преобразовать массив байтов utf8 в массив байтов с шестнадцатеричными значениями, но это не сработало так хорошо.
Я надеюсь, что кто — нибудь сможет мне помочь!
Спасибо, радсн!