为HMAC准备字符串

时间:2012-10-23 18:16:42

标签: python node.js hmac

我正在编写一个使用HMAC进行消息身份验证的Web服务。我在准备摘要的“数据”时遇到了一些问题,并且我在Python和NodeJS中获得了相同“数据”的不同摘要。

我很确定这个问题是由编码引起的,但我不确定如何最好地解决这个问题。

Python代码:

import hmac
from hashlib import sha1

f = open('../test.txt')
raw = f.read()

raw = raw.strip()

hm = hmac.new('12345', raw, sha1)
res = hm.hexdigest()
print res

>> 5bff447a0fb82f3e7572d9fde362494f1ee2c25b

NodeJS(咖啡)代码:

fs = require 'fs'
http = require 'http'
{argv} = require 'optimist'
crypto = require 'crypto'

# Load the file
file = fs.readFileSync argv.file, 'utf-8'
file = file.trim()

# Create the signature
hash = crypto.createHmac('sha1', '12345').update(file).digest('hex')
console.log(hash)

>> a698f82ea8ff3c4e9ffe0670be2707c104d933aa

编辑:此外,raw的长度比文件长2个字符,但我无法确定这两个字符的来源。

2 个答案:

答案 0 :(得分:4)

这是您从文件系统读取的数据的编码问题,与您使用的算法没有任何关系。

当您使用Python和JavaScript中的字符串数据时,您应该非常小心存储数据的编码。尝试使用数据,就像字符串一样(特别是具有编码等属性) ,或与原始数据"一样。在阅读和签署数据时,您不应该关心编码,并尝试将数据用作" raw"尽可能用你的语言。

需要注意的一些要点:

  • 文件系统商店" raw" bytes,并且对文件的内容和编码一无所知。此外,对于某些文件(例如,jpegs),"编码"概念毫无价值
  • 这同样适用于加密算法。它们使用原始字节,并且不知道它的#34;字符表示"。这就是为什么数字签名在各种二进制文档等方面都能很好地工作的原因。
  • javascript中的
  • trim()或python中的strip()使用字符串,它们的行为可能因底层编码而异(例如,在python中尝试u's '.encode('utf-16').strip().decode('utf-16'))。如果可能的话,我宁愿避免使用修剪,也不要混淆你处理数据的方式。
  • Python 2.x(我想,也是Javascript)有一组规则用于字符串和原始数据之间的隐式转换。

在您的代码中,您使用Python中的二进制数据,但在定义要读取的文件的编码时,请在JavaScript中转换为字符串。显然,在加密模块中有一种从utf-8隐式转换回原始字符串,但我不知道它的作用。

here中所述,在node.js中处理原始字符串的最犹豫方式是使用缓冲区。你可以从文件系统中读取缓冲区,但不幸的是,nodejs加密库还没有支持它们。如上所述here

  

在存在a的概念之前,Crypto模块已添加到Node   统一的Stream API,之前有Buffer对象进行处理   二进制数据。

     

因此,流媒体课程没有找到典型的方法   其他Node类,许多方法接受并返回二进制编码   字符串默认情况下而不是缓冲区。

他说,为了使示例有效,目前的方法是通过传递"二进制"来读取数据。作为电话会议的第二个参数:

file = fs.readFileSync argv.file, "binary"

另外,正如我所说,我宁愿避免剥离我刚从文件中读取的数据。

答案 1 :(得分:1)

尝试一些想法:

  • 检查raw的长度是否与file
  • 相同
  • 以二进制方式打开f
  • import codecs并使用codecs.open编码
  • strip将从Python中删除字符串开头和结尾的所有空格 - 我认为trim只会从最后删除。因此,您可能希望rstrip()可能设置显式字符以获得相同的行为