简体   繁体   English

JavaScript加密哈希转换为Python 3

[英]JavaScript crypto hashing translation to Python 3

I am trying to make a Python 3 application to download weather data from my account at http://www.osanywhereweather.com . 我正在尝试制作一个Python 3应用程序,以从我位于http://www.osanywhereweather.com的帐户下载天气数据。 I have found JavaScript source code that does exactly this at https://github.com/zrrrzzt/osanywhereweather . 我在https://github.com/zrrrzzt/osanywhereweather找到了可以做到这一点的JavaScript源代码。 I am assuming that the github code works. 我假设github代码有效。 When inspecting the source of osanywhereweather.com, it seems to me that the github code resembles that very much. 在检查osanywhereweather.com的源代码时,在我看来github代码非常相似。

I am new to Python 3 and I have never coded in JavaScript, and I know nothing about cryptographics. 我是Python 3的新手,我从未用JavaScript编写过代码,对密码学一无所知。 I have, however, done a fair share of coding over the last 35 or years, so I read code fairly well. 但是,过去35年来,我在编码方面做得相当不错,因此我读得很好。 I therefore thought it would be relatively easy to translate the github JavaScript code to Python 3. I was wrong, it seems. 因此,我认为将github JavaScript代码转换为Python 3相对容易。看来是错误的。

The code of interest is the part of the code that hashes e-mail and password together with a "challenge" received from osanwhereweather.com in order to authenticate me. 感兴趣的代码是该代码的一部分,该代码对电子邮件和密码以及从osanwhereweather.com收到的“挑战”进行哈希处理,以对我进行身份验证。

I have not been able to test the JavaScript code, but as I said I think it compares well with the source of the osanywhereweather.com page. 我无法测试JavaScript代码,但是正如我所说,我认为它与osanywhereweather.com页面的源代码比较好。 By analyzing the traffic in my web browser, I can see the information exchanged between osanywhereweather.com and my browser, so that I have got a consistent set of challenge and saltedHash . 通过分析Web浏览器中的流量,我可以看到osanywhereweather.com和我的浏览器之间交换的信息,因此我得到了一系列一致的challengesaltedHash

When trying to create the same saltedHash based on the corresponding challenge with my Python 3 code, I get a different result. 当尝试使用Python 3代码基于相应的challenge创建相同的saltedHash ,得到了不同的结果。

I have tried internet searches to see if I can find out what I'm doing wrong, but to no avail. 我尝试了互联网搜索,以查看是否可以找到自己在做错的事情,但无济于事。 If anyone is proficient in JavaScript, Python and cryptographics and is able to point out what I'm doing wrong, I would indeed be grateful. 如果有人精通JavaScript,Python和加密技术,并且能够指出我做错了什么,那我将不胜感激。

JavaScript code: JavaScript代码:

'use strict';

var crypto = require('crypto');

function osaHash(email, password) {
  var shasum = crypto.createHash('sha1').update(email);
  var e = '$p5k2$2710$' + shasum.digest('hex').toString().substring(0, 8);
  var res = crypto.pbkdf2Sync(password, e, 1e4, 32, 'sha256');
  var r = res.toString('base64').replace(/\+/g, '.');

  return e + '$' + r;
}

function createHash(opts, callback) {

  if (!opts) {
    return callback(new Error('Missing required input: options'), null);
  }

  if (!opts.email) {
    return callback(new Error('Missing required param: options.email'), null);
  }

  if (!opts.password) {
    return callback(new Error('Missing required param: options.password'), null);
  }

  if (!opts.challenge) {
    return callback(new Error('Missing required param: options.challenge'), null);
  }

  var hash = osaHash(opts.email, opts.password);
  var hmac = crypto.createHmac('sha1', hash).update(opts.challenge);
  var saltedHash = hmac.digest('hex');

  return callback(null, saltedHash);
}

module.exports = createHash;

Python 3 code: Python 3代码:

import hmac
import hashlib
import base64

e_mail = 'me@mydomain.com'
password = 'Secret'

''' challenge is received from osanywhereweather.com '''
challenge = '15993b900f954e659a016cf073ef90c1' 

shasum           = hashlib.new('sha1')
shasum.update(e_mail.encode())
shasum_hexdigest = shasum.hexdigest()
shasum_substring = shasum_hexdigest[0:8]
e                = '$p5k2$2710$' + shasum_substring

res = hashlib.pbkdf2_hmac('sha256',password.encode(),e.encode(),10000,32)
r = base64.b64encode(res,b'./')
hashstr = str(e) + '$' + str(r)

hmac1 = hmac.new(challenge.encode(), hashstr.encode(), 'sha1')
saltedHash = hmac1.hexdigest()
hashstr = str(e) + '$' + str(r)

In the above line, str(r) will give you: "b'ZogTXTk8T72jy01H9G6Y0L7mjHHR7IG0VKMcWZUbVqQ='" . 在上面的行中, str(r)将为您提供: "b'ZogTXTk8T72jy01H9G6Y0L7mjHHR7IG0VKMcWZUbVqQ='"

You need to use r.decode() to get "ZogTXTk8T72jy01H9G6Y0L7mjHHR7IG0VKMcWZUbVqQ=" . 您需要使用r.decode()来获取"ZogTXTk8T72jy01H9G6Y0L7mjHHR7IG0VKMcWZUbVqQ="

hashstr = str(e) + '$' + r.decode()

UPDATE 1 更新1

Arugments to hmac.new should be fixed: 修正hmac.new

hmac1 = hmac.new(hashstr.encode(), challenge.encode(), 'sha1')

UPDATE 2 更新2

According to OP's comment, OP doesn't need to do the following. 根据OP的评论,OP不需要执行以下操作。

Another thing is that, crypto.pbkdf2Sync seems does not respect digest argument. 另一件事是, crypto.pbkdf2Sync似乎不尊重digest参数。 It seems always use sha1 digest (At least in my system, NodeJS 0.10.25). 似乎总是使用sha1摘要(至少在我的系统中,NodeJS 0.10.25)。 So you need to specify sha1 in python side: 因此,您需要在python端指定sha1

res = hashlib.pbkdf2_hmac('sha1', password.encode(), e.encode(), 10000, 32)

Based on falsetru's response, the following Python 3 code has been verified to work with the osanywhereweather.com site: 基于falsetru的响应,以下python 3代码已经过验证,可与osanywhereweather.com网站一起使用:

import hmac
import hashlib
import base64

e_mail = 'me@mydomain.com'
password = 'Secret'

''' challenge is received from osanywhereweather.com '''
challenge = '15993b900f954e659a016cf073ef90c1' 

shasum           = hashlib.new('sha1')
shasum.update(e_mail.encode())
shasum_hexdigest = shasum.hexdigest()
shasum_substring = shasum_hexdigest[0:8]
e                = '$p5k2$2710$' + shasum_substring

res = hashlib.pbkdf2_hmac('sha256',password.encode(),e.encode(),10000,32)
r = base64.b64encode(res,b'./')
hashstr = str(e) + '$' + r.decode()

hmac1 = hmac.new(hashstr.encode(), challenge.encode(), 'sha1')
saltedHash = hmac1.hexdigest()

Thank you to falsetru! 谢谢falsetru!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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