2012-04-09 85 views
4

我试图将ASP/VBScript OAuth库转换为VBA。其中一个挑战是这样一行代码:Base64 HMAC SHA1 VBA中的字符串

Get_Signature = b64_hmac_sha1(strSecret, strBaseSignature) 

这个函数,b64_hmac_sha1实际上是一个包含在JavaScript库中的函数。在我看来,从VBA调用JavaScript函数是相当不切实际的。

因为我对加密知之甚少,所以我不清楚b64_hmac_sha1函数的功能。 HMAC SHA1与SHA1不同吗?

我半怀疑我可能能够在网上找到一些VBA代码来做我需要做的事情,只要我明白这个功能实际上在做什么。如果我找不到现有的函数,那么我可能会编写一个使用.NET密码库的函数(如果您知道如何,实际上可以从VBA调用.NET密码函数库)。

我不是在找人把这个JavaScript转换成VBA。我只是想了解这个b64_hmac_sha1函数输出的是什么,所以我可以尝试在可能的情况下找到在VBA中实现相同输出的方法。

此JavaScript库的副本可在此网站上查看。您必须向下滚动浏览VBScript到JavaScript部分。 http://solstice.washington.edu/solstice/ASP_Signing_REST_Example

EDIT1:
好了,这里是我结束了编写和使用的功能:

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 

使用此功能:

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

我想补充一点,此功能对于OAuth 1.0是必需的,但对OAuth 2.0不是必需的。 – HK1 2012-04-09 13:17:14

回答

5

HMAC是转动的构建哈希函数,如SHA1,到Message Authentication Code(MAC)。

正常散列函数没有任何与之相关的秘密数据。这意味着任何人都可以计算摘要,假设他们有原始输入。 HMAC使用一个密钥,这样只有拥有该密钥的人才能计算输出。

假设我有一个文件file.txt。我想发送给你,我们需要确保没有人篡改它。对不起,我没有聪明的方法来表示这只是文字。

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

然后,通过计算您自己的SHA1摘要来验证结果,并验证它是否与我发送给您的结果相匹配。

现在假设攻击者在中间。不幸的是,由于没有涉及秘密,攻击者可以修改文件并计算他自己的文件/摘要对。当你计算你的版本时,它会匹配他发给你的东西,而你不会更聪明。

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

随着HMAC,我们添加一个秘密密钥的计算。

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

当你计算你的版本时,你也应用密钥,结果匹配。攻击者在不知道密钥的情况下不能替换摘要。

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

HMAC是一种非常具体的添加密钥的方式。不幸的是,简单的将密钥连接到文件末尾的方法,或者在哈希之前预先挂起的方法容易受到不同的攻击(例如长度扩展攻击)的影响。

B64是Base64编码输出,使它变得漂亮。

这段代码最终要做的是取一些输入和一些密钥,并计算一个160位的摘要,然后用base64编码结果。

还有就是SHA1 HMAC in .NET

This的实现看起来像VBA

我希望这回答的不够好,或者不够清晰Base64编码的实现。如果文字混淆,请告诉我。我尝试了一些如何表达的路线,而且没有一个看起来很清楚。

+0

感谢您的帮助。我编写了我的函数,并将它们发布在“Edit1”下的问题中。 – HK1 2012-04-09 04:33:53

+0

很高兴帮助。一切正常吗?尽我从未写过VB或VBA,顺序看起来是正确的,尽我所知。 – mfanto 2012-04-09 04:37:45

+0

我想我不确定它是否正常工作。我会举一个例子。 – HK1 2012-04-09 04:47:52

0

您采写:

在我看来,调用由VBA JavaScript函数是相当不切实际的。

这是一个错误的判断。

JavaScript可以很容易地打包成Windows脚本组件(WSC),然后通过COM,从VBA,Perl,VB6或什么都可以。

这里的包装JavaScript作为一种WSC和调用它的一个例子:https://stackoverflow.com/a/849970/48082

因此,你的问题应该很容易解决的。

+0

我实际上碰到了这个选项。我想我不会为调用外部COM服务器而疯狂,除非我绝对必须这样做。 – HK1 2012-04-09 04:18:49