我正在尝试制作一个Python3应用程序,从我在http://www.osanywhereweather.com的帐户下载天气数据。我已经找到了JavaScript源代码,它在https://github.com/zrrrzzt/osanywhereweather上就是这样做的。我假设github代码可以工作。在我看来,当检查osanywhereweather.com的源代码时,github代码非常相似。
我是Python3的新手,我从来没有用JavaScript编码过,我对密码学一无所知。然而,在过去的35年或几年里,我已经完成了相当一部分的编码工作,所以我读得相当好。因此,我认为将github JavaScript代码转换为Python3相对容易,我似乎错了。
感兴趣的代码是散列电子邮件和密码的代码的一部分,以及从osanwhereweather.com接收到的一个“挑战”,以验证我的身份。
我无法测试JavaScript代码,但正如我所说的,我认为它与osanywhereweather.com页面的源代码比较好。通过分析我的web浏览器中的流量,我可以看到osanywhereweather.com和我的浏览器之间交换的信息,因此我得到了一组一致的challenge和saltedHash。
当尝试使用我的Python3代码基于相应的saltedHash创建相同的challenge时,我得到了不同的结果。
我尝试过网络搜索,看看我是否能找出我做错了什么,但没有结果。如果有人精通JavaScript、Python和密码学,并且能够指出我做错了什么,我将非常感激。
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代码:
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()发布于 2015-11-19 08:26:15
hashstr = str(e) + '$' + str(r)在上面的行中,str(r)将给出:"b'ZogTXTk8T72jy01H9G6Y0L7mjHHR7IG0VKMcWZUbVqQ='"。
您需要使用r.decode()来获取"ZogTXTk8T72jy01H9G6Y0L7mjHHR7IG0VKMcWZUbVqQ="。
hashstr = str(e) + '$' + r.decode()更新1
对hmac.new的装备应固定如下:
hmac1 = hmac.new(hashstr.encode(), challenge.encode(), 'sha1')更新2
根据OP的评论,OP不需要执行以下操作。
另一件事是,crypto.pbkdf2Sync似乎不尊重digest的论点。它似乎总是使用sha1摘要(至少在我的系统中,NodeJS 0.10.25)。因此,您需要在python端指定sha1:
res = hashlib.pbkdf2_hmac('sha1', password.encode(), e.encode(), 10000, 32)发布于 2015-11-19 13:00:54
基于falsetru的响应,已经验证了以下Python3代码可用于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()谢谢你的福尔斯图!
https://stackoverflow.com/questions/33797236
复制相似问题