在 VB.NET 中为 HMAC SHA1 编码换行符

Encoding newline in VB.NET for HMAC SHA1

我在使用 OAuth 验证 API 时遇到问题。我可以让它在 Python 中正常工作,但在 VB.Net 中却不行。我意识到问题是 SHA1 算法在 Python 和 VB.NET 中返回不同的值,因为我认为是相同的消息。这似乎只有在消息中有换行符“\n”时才会出现这种情况(API 调用必须有换行符)。使用 Environment.NewLine 似乎没有帮助。

我正在使用的代码(基于 this answer)在这里,以及我从 Python 程序中获得的预期值:

Public Sub Main()           
    ' Expect D/5B78PD9pFhmqZQi3eenPBy6ks=
    ' Get    D/5B78PD9pFhmqZQi3eenPBy6ks=
    console.writeline(getHash("a", "msg"))

    ' Expect yuuq6RwtwkoJ6n3PquGFx60MLas=
    ' Get    uv4AwQjvYeCTajhHw7EFtPlJfCE=
    console.writeline(getHash("a", "msg\n"))

    ' Expect yuuq6RwtwkoJ6n3PquGFx60MLas=       
    ' Get efRfAnmIN/C/YX/UPHVPFY5VjJg=
    console.writeline(getHash("a", "msg" + Environment.NewLine))

End Sub

Public Function getHash(ByVal key As String, ByVal msg As String) As String
    Dim myEncoder As New System.Text.UTF8Encoding
    Dim keyBytes() As Byte = myEncoder.GetBytes(key)
    Dim msgBytes() As Byte = myEncoder.GetBytes(msg)

    Dim myHMACSHA1 As New System.Security.Cryptography.HMACSHA1(keyBytes)
    Dim HashCode As Byte() = myHMACSHA1.ComputeHash(msgBytes)

    Return Convert.ToBase64String(HashCode)
End Function

如果有用,我的 Python 程序是:

import base64
import hashlib
import hmac

key = "a"
msg = "msg\n"
key_byte = key.encode('utf-8')
msg_byte = msg.encode('utf-8')

h = hmac.new(key_byte, msg_byte, hashlib.sha1)
print base64.b64encode(h.digest())   # yuuq6RwtwkoJ6n3PquGFx60MLas=

我猜这与换行符的编码方式有关,但我不知道如何解决它。

首先我想指出 VB.NET 中的 \n 不代表换行符。它实际上会变成 \n.

Environment.NewLine adapts to the current OS. Different operating systems use different line endings. The issue here is that the Python code is using a Line Feed character (\n) as a new line indicator, but since Environment.NewLine adapts to the OS it will return Windows' line ending, which is Carriage Return + 换行 (\r\n).

因此,如果您希望它与 Python 代码相匹配,您必须确保只插入一个换行 。例如:

Console.WriteLine(getHash("a", "msg" & vbLf))