如何生成用于数据传输的 HMAC-SHA-256 登录 javascript?

问题描述 投票:0回答:3

我有一个 Angular 项目,我必须在其中实现 datatrans 付款。但我无法生成付款标志。

我正在按照此链接上给出的流程(在此处输入链接描述)来生成标志。

但我无法实现它。

我正在使用 Angular 库 crypto-js 生成 HMAC-SHA-256 签名字符串。

这是我的 JavaScript 代码。

const merchantId = 'xxxxxxx';
const refNo = '1234567890';
const amount = 0;
const currency = 'CHF';
const theme = 'DT2015';
const paymentmethod = 'VIS';

const stringSs = merchantId+amount+currency+refNo;

const base = 16;
// My Hmac Key
const s = 'fa3d0ea1772cf21e53158283e4f123ebf1eb1ccfb15619e2fc91ee6860a2e5e48409e902b610ce5dc6f7f77fab8affb60d69b2a7aa9acf56723d868d36ab3f32';

// Step 1: Code to generate hex to byte of hmac key
const a = s.replace(/../g, '$&_').slice (0, -1).split ('_').map ((x) => parseInt (x, base));

//  Step 3: Sign the string with HMAC-SHA-256 together with your HMAC key
const signedString = HmacSHA256(a, stringSs);

// Step 4: Translate the signature from byte to hex format
const signString = enc.Hex.stringify(signedString);

你能帮我解决这个问题,建议我做错了什么或以什么方式可以实现它。

javascript angular sha256 cryptojs
3个回答
7
投票

您可以使用加密来完成(无需安装额外的库)

// Typescript
import * as crypto from 'crypto';

function signKey (clientKey: string, msg: string) {
    const key = new Buffer(clientKey, 'hex');
    return crypto.createHmac('sha256', key).update(msg).digest('hex');
}
// Javascript
const crypto = require('crypto')

function signKey (clientKey, msg) {
    const key = new Buffer(clientKey, 'hex');
    return crypto.createHmac('sha256', key).update(msg).digest('hex');
}
signKey(s, stringSs)

1
投票

要按要求回答 crypto-js 的问题(请参阅https://github.com/brix/crypto-js),以下内容即可解决问题:

// Javascript; example from datatrans documentation using a random key
stringSs ='3000017692850CHF91827364';
key='1ca12d7c0629194a9f9d0dbbc957709dd3aed385925b077e726813f0b452de6a38256abd1116138d21754cfb33964b6b1aaa375b74d3580fcda916898f553c92';
expectedSign='d7dee9ae1e542bc02bcb063a3dd3673871b2e43ccb4c230f26e8b85d14e25901';

signedString = CryptoJS.HmacSHA256(stringSs, CryptoJS.enc.Hex.parse(key));
resultSign = CryptoJS.enc.Hex.stringify(signedString);

// now resultSign == expectedSign is true :-)

忍者神龟方法几乎是正确的,除了步骤 1(十六进制到字节)之外。使用 Crypto-JS 的内置函数来代替,一切都会按预期工作。


0
投票

现代浏览器内置加密功能,不需要 npm 模块,

这是一个粗略的 TypeScript 实现,大量借鉴了 https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest(我希望这可以改进):

async function signString(s: string): Promise<string> {
  const msgUint8 = new TextEncoder().encode(s)
  const buf = await crypto.subtle.digest('SHA-256', msgUint8)
  const hashArray = Array.from(new Uint8Array(buf))
  return hashArray.map(b => b.toString(16).padStart(2, '0')).join(''))
}
© www.soinside.com 2019 - 2024. All rights reserved.