简体   繁体   中英

Crypto hmac conversion from Python to Javascript

I'm trying to convert the following function from Python to Javascript. Currently concentrating on the generation of the signature.

def prepare_url(self, segments, params={}):
        if self.token is not None:
            sig = hmac.new(self.token.key.encode(), digestmod=hashlib.sha1)
            sig.update(self.method.lower().encode())
            sig.update(self.service.lower().encode())
            

            ts = self.get_timestamp(self.token.server_offset)
            sig.update(ts.encode())
            params["timestamp"] = ts

            sig.update(self.token.identifier.lower().encode())
 
            params["signature-method"] = "auth"
            params["signature-version"] = self.version
            params["signature"] = base64.standard_b64encode(sig.digest())
 
        self.url = "%s/%s/%d/" % (self.base_path, self.service, self.version)
        self.url += "/".join([urllib.parse.quote(s) for s in segments])
        if params:
            self.url += "?%s" % urllib.parse.urlencode(params)

In Javascript I'm using the crypto library and have the following code:

import crypto from 'crypto';

const KEY = '5d016f32-452f-4b9b-8e81-641e14d4d98c';
const METHOD = 'get';
const SERVICE = 'data';
const date = (new Date()).toISOString().slice(0, 19);

const encoded = crypto.createHash('sha1')
    .update(KEY)
    .update(METHOD.toLowerCase())
    .update(SERVICE.toLowerCase())
    .update(date)
    .digest('hex');
console.log(encoded);

const baseEncoded = btoa(encoded);
console.log(baseEncoded);

However the end codes are not comparable.

Python generates using the given inputs: b'oV4RJ6pAz+hxZsxeQthx8gZrhAY='

Javascript generates: YTZjMmIyYjQzOGEwZGUxZTU1YTNjMWVlYjA3MTA3NTFmODc0MDM3ZQ==

I googled around but could not find what to change to make this work. In python the digest is hashlib.sha1, this is not available in crypto.

Any pointers?

Below are the codes Python generates at each of the update steps.

-----> key: b'bnAcIlriz+t4hTQLBrnjI1aeXBI='
-----> method: b'rc1Y6wKZo8pDKHmhjVNDkhcVNKM='
-----> Service: b'/urBh6Yqk6QI39JhYtSMI9P9QS8='
-----> Time: 5d016f32-452f-4b9b-8e81-641e14d4d98c
-----> Identifier: b'oV4RJ6pAz+hxZsxeQthx8gZrhAY='
-----> FINAL: b'oV4RJ6pAz+hxZsxeQthx8gZrhAY='

Solution:

const encoded = crypto.createHmac('sha1', key)
    .update(METHOD.toLowerCase())
    .update(SERVICE.toLowerCase())
    .update(date)
    .update(identify)
    .digest('base64');

Based on the feedback from @PresidentJamesK.Polk I was able to figure this out.

const encoded = crypto.createHmac('sha1', key)
    .update(METHOD.toLowerCase())
    .update(SERVICE.toLowerCase())
    .update(date)
    .update(identify)
    .digest('base64');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM