简体   繁体   English

Base64 VBA 中的 HMAC SHA1 字符串

[英]Base64 HMAC SHA1 String in VBA

I'm trying to convert an ASP/VBScript OAuth library to VBA. One of the challenges is this line of code:我正在尝试将 ASP/VBScript OAuth 库转换为 VBA。挑战之一是这行代码:

Get_Signature = b64_hmac_sha1(strSecret, strBaseSignature)

This function, b64_hmac_sha1 is actually a function contained in a JavaScript library.这个function,b64_hmac_sha1其实是一个function包含在一个JavaScript库中。 It appears to me that calling a JavaScript function from VBA is fairly impractical.在我看来,从 VBA 调用 JavaScript function 是相当不切实际的。

Because I know so little about encryption, it's not even clear to me what this b64_hmac_sha1 function does.因为我对加密知之甚少,所以我什至不清楚这个 b64_hmac_sha1 function 是做什么的。 Is HMAC SHA1 different from SHA1? HMAC SHA1 与 SHA1 不同吗?

I half suspect I might be able to find some VBA code online to do what I need to do if I just understood what this function is actually doing.我有点怀疑,如果我只了解这个 function 实际在做什么,我也许可以在网上找到一些 VBA 代码来做我需要做的事情。 If I do not find an existing function, I could possibly write one that would use the .NET Cryptography library (you can actually call the .NET cryptography libraries from VBA if you know how).如果我找不到现有的 function,我可能会编写一个使用 .NET 密码库的密码库(如果您知道如何操作,您实际上可以从 VBA 调用 .NET 密码库)。

I'm not looking for someone to convert this JavaScript to VBA. I'm only trying to understand what it is that this b64_hmac_sha1 function is outputting so I can try to find ways to achieve the same output in VBA if possible.我不是在找人将这个 JavaScript 转换为 VBA。我只是想了解这个 b64_hmac_sha1 function 输出的是什么,所以如果可能的话,我可以尝试找到在 VBA 中实现相同 output 的方法。

A copy of this JavaScript library is visible on this website.这个 JavaScript 图书馆的副本可以在这个网站上看到。 You'll have to scroll down past the VBScript to the JavaScript section.您必须向下滚动 VBScript 到 JavaScript 部分。 http://solstice.washington.edu/solstice/ASP_Signing_REST_Example http://solstice.washington.edu/solstice/ASP_Signing_REST_Example

Edit1:编辑1:
OK, so here's the functions I ended up writing and using:好的,下面是我最终编写和使用的函数:

Public Function Base64_HMACSHA1(ByVal sTextToHash As String, ByVal sSharedSecretKey As String)

    Dim asc As Object, enc As Object
    Dim TextToHash() As Byte
    Dim SharedSecretKey() As Byte
    Set asc = CreateObject("System.Text.UTF8Encoding")
    Set enc = CreateObject("System.Security.Cryptography.HMACSHA1")

    TextToHash = asc.Getbytes_4(sTextToHash)
    SharedSecretKey = asc.Getbytes_4(sSharedSecretKey)
    enc.Key = SharedSecretKey

    Dim bytes() As Byte
    bytes = enc.ComputeHash_2((TextToHash))
    Base64_HMACSHA1 = EncodeBase64(bytes)
    Set asc = Nothing
    Set enc = Nothing

End Function

Private Function EncodeBase64(ByRef arrData() As Byte) As String

    Dim objXML As MSXML2.DOMDocument
    Dim objNode As MSXML2.IXMLDOMElement

    Set objXML = New MSXML2.DOMDocument

    ' byte array to base64
    Set objNode = objXML.createElement("b64")
    objNode.DataType = "bin.base64"
    objNode.nodeTypedValue = arrData
    EncodeBase64 = objNode.Text

    Set objNode = Nothing
    Set objXML = Nothing

End Function

Using this function:使用这个 function:

Debug.Print Base64_HMACSHA1("abc", "123")
VAsMU9SSWDe9krP3Gr56nXC2dsQ=

HMAC is a construct for turning a hash function, like SHA1, into a Message Authentication Code (MAC). HMAC 是一种将 hash function(如 SHA1)转换为消息验证码(MAC) 的结构。

Normal hash functions don't have any secret data associated with it.正常的 hash 函数没有任何与之关联的秘密数据。 This means that anyone can compute the digest, assuming they have the original input.这意味着任何人都可以计算摘要,假设他们有原始输入。 HMAC uses a secret key, so that only those in possession of the key can compute outputs. HMAC 使用秘密密钥,因此只有拥有密钥的人才能计算输出。

Suppose I have a file, file.txt.假设我有一个文件,file.txt。 I want to send this to you, and we need to make sure nobody tampers with it.我想把这个发给你,我们需要确保没有人篡改它。 Sorry, I have no clever way to represent this with just text.抱歉,我没有巧妙的方法来仅用文本来表示。

me -> file.txt -> you
me -> SHA1(file.txt) -> you

Then you verify the result by computing your own SHA1 digest, and verifying it matches what I sent you.然后您通过计算您自己的 SHA1 摘要来验证结果,并验证它与我发送给您的内容相匹配。

Now suppose an attacker was in the middle.现在假设攻击者在中间。 Unfortunately, because there is no secret involved, the attacker can modify the file, and compute his own file/digest pair.不幸的是,因为没有涉及秘密,攻击者可以修改文件,并计算他自己的文件/摘要对。 When you compute your version, it'll match what he sent you, and you'll be none the wiser.当你计算你的版本时,它会与他发送给你的相匹配,而你不会变得更聪明。

me -> file.txt -> attacker -> modified.txt -> you
me -> SHA1(file.txt) -> attacker -> SHA1(modified.txt) -> you

With HMAC, we add a secret key to the computation.使用 HMAC,我们在计算中添加了一个密钥。

me -> file.txt -> you
me -> SHA1_HMAC(file.txt, our_secret) -> you

When you compute your version, you apply the secret key as well, and the result matches.当你计算你的版本时,你也应用了密钥,结果匹配。 The attacker, without knowledge of the key, can't replace the digest.攻击者在不知道密钥的情况下无法替换摘要。

me -> file.txt -> attacker -> modified.txt -> you 
me -> SHA1(file.txt) -> attacker -> SHA1_HMAC(modified.txt, // DOESN'T KNOW KEY) -> you

HMAC is a very specific way of adding the secret key. HMAC 是一种非常特殊的添加密钥的方法。 Unfortunately, simple methods of just concatenating a key to the end of the file, or pre-pending it before hashing, are vulnerable to different attacks (length extension attacks, for example).不幸的是,仅将密钥连接到文件末尾或在散列之前预先挂起的简单方法容易受到不同的攻击(例如长度扩展攻击)。

The B64 is Base64 encoding the output, to make it pretty. B64 是 Base64 编码 output,让它漂亮。

What this code is ultimately doing is taking some input, and some secret key, and computing a 160-bit digest, and base64 encoding the result.这段代码最终要做的是获取一些输入和一些密钥,计算一个 160 位的摘要,并对结果进行 base64 编码。

There is an implementation of SHA1 HMAC in .NET .NET中有SHA1 HMAC的实现

This looks like an implementation of Base64 for VBA 看起来像是 VBA 的 Base64 的实现

I hope this answers it well enough, or clear enough.我希望这能很好地回答它,或者足够清楚。 If the text is confusing, please let me know.如果文字令人困惑,请告诉我。 I tried a couple routes of how to express it, and none of them seemed that clear.我尝试了几种表达方式,但似乎都不是那么清楚。

You have written:你写:

It appears to me that calling a JavaScript function from VBA is fairly impractical.在我看来,从 VBA 调用 JavaScript function 是相当不切实际的。

That is a misjudgment.那是误判。

Javascript can be easily packaged as a Windows Script Component (WSC) and then invokved via COM, from VBA, Perl, VB6, or what-have-you. Javascript 可以轻松打包为 Windows 脚本组件 (WSC),然后通过 COM、VBA、Perl、VB6 或其他任何方式调用。

Here's an example of packaging Javascript as a WSC and invoking it: https://stackoverflow.com/a/849970/48082下面是将 Javascript 打包为 WSC 并调用它的示例: https://stackoverflow.com/a/849970/48082

Therefore, your problem should be easily solvable.因此,您的问题应该很容易解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM