我正在编写一个使用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个字符,但我无法确定这两个字符的来源。
答案 0 :(得分:4)
这是您从文件系统读取的数据的编码问题,与您使用的算法没有任何关系。
当您使用Python和JavaScript中的字符串数据时,您应该非常小心存储数据的编码。尝试使用数据,就像字符串一样(特别是具有编码等属性) ,或与原始数据"一样。在阅读和签署数据时,您不应该关心编码,并尝试将数据用作" raw"尽可能用你的语言。
需要注意的一些要点:
trim()
或python中的strip()
使用字符串,它们的行为可能因底层编码而异(例如,在python中尝试u's '.encode('utf-16').strip().decode('utf-16')
)。如果可能的话,我宁愿避免使用修剪,也不要混淆你处理数据的方式。在您的代码中,您使用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()
可能设置显式字符以获得相同的行为