簡體   English   中英

JavaScript加密哈希轉換為Python 3

[英]JavaScript crypto hashing translation to Python 3

我正在嘗試制作一個Python 3應用程序,以從我位於http://www.osanywhereweather.com的帳戶下載天氣數據。 我在https://github.com/zrrrzzt/osanywhereweather找到了可以做到這一點的JavaScript源代碼。 我假設github代碼有效。 在檢查osanywhereweather.com的源代碼時,在我看來github代碼非常相似。

我是Python 3的新手,我從未用JavaScript編寫過代碼,對密碼學一無所知。 但是,過去35年來,我在編碼方面做得相當不錯,因此我讀得很好。 因此,我認為將github JavaScript代碼轉換為Python 3相對容易。看來是錯誤的。

感興趣的代碼是該代碼的一部分,該代碼對電子郵件和密碼以及從osanwhereweather.com收到的“挑戰”進行哈希處理,以對我進行身份驗證。

我無法測試JavaScript代碼,但是正如我所說,我認為它與osanywhereweather.com頁面的源代碼比較好。 通過分析Web瀏覽器中的流量,我可以看到osanywhereweather.com和我的瀏覽器之間交換的信息,因此我得到了一系列一致的challengesaltedHash

當嘗試使用Python 3代碼基於相應的challenge創建相同的saltedHash ,得到了不同的結果。

我嘗試了互聯網搜索,以查看是否可以找到自己在做錯的事情,但無濟於事。 如果有人精通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()
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)

基於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()

謝謝falsetru!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM