ASP/VBScript巧用CAPICOM实现随机数、Hash(MD5/SHA1)和Base64编解码

!本文可能 超过1年没有更新,今后内容也许不会被维护或者支持,部分内容可能具有时效性,涉及技术细节或者软件使用方面,本人不保证相应的兼容和可操作性。

其实很早就想介绍这个Windows内置的ActiveX/COM组件,我前面有一篇文章介绍如何借用.NET Framework实现类似于SHA1和MD5哈希算法,如果大家对此感兴趣也可以看一下。

好,言归正传,今天我要介绍的是如何让VBScript利用Windows原生自带的CAPICOM组件来实现随机数、Hash(MD5/SHA1)以及Base64算法,当然在VBScript的世界里,这些算法都有免组件的纯代码实现,当然使用组件的好处就是代码简洁和运行效率的提高,所以我们不妨尝试一下。
既然今天介绍的主角是CAPICOM,当然我们要推荐参考微软的MSDN文档,大家不妨先大致浏览一番,可能大家很快发现下面这段提示:

CAPICOM is a 32-bit only component that is available for use in the following operating systems: Windows Server 2008, Windows Vista and Windows XP. Instead, use the .NET Framework to implement security features.

由此可见非常遗憾的是CAPICOM仅仅是32位Windows XP、Windows Vista以及Windows 2008系统上才自带(对于64位系统可以参考文章在64位系统中使用CAPICOM),所以在包含CAPICOM特性代码部署到服务器上之前需要测试一下当前系统是否支持,如果不支持只有考虑.NET或者原生代码的实现了。

CAPICOM有很多对象(Objects),这里我也不一一介绍,主要关注的是CAPICOM.UtilitiesCAPICOM.HashedData。本文也是通过这两个对象实现所需要的算法功能的。

CAPICOM.Utilities

实现随机数

Function GetRandom()
    Dim objCapiCom
    Set objCapiCom = CreateObject("CAPICOM.Utilities.1")
    GetRandom = objCapiCom.GetRandom(32, -1)
    Set objCapiCom = Nothing
End Function

可能大家要问为什么VBScript语言自带随机数功能,我们还需要使用CAPICOM来生成随机数,实际上我们通过脚本语言生成的随机数是伪随机数,当然这些伪随机数可以应用于一些要求不高的场合,伪随机数是通过算法和数学运算生成的模拟随机数,对于加密这类应用来说这种随机数是不安全的,而真正的随机数是通过硬件噪音生成的,比如在Linux及其他类Unix系统下,可以通过/dev/random或者/dev/urandom获得,因为这里我们实现的系统是Windows,所以可以变通的通过CAPICOM获取。

大家可能注意到上述代码objCapiCom.GetRandom(32, -1)中的第二个参数-1,微软给出的定义如下:

Const CAPICOM_ENCODE_ANY    = -1
Const CAPICOM_ENCODE_BASE64 =  0
Const CAPICOM_ENCODE_BINARY =  1

关于这些常量定义的实际含义可以参考MSDN文档

实现Base64编码和解码

在文章《Base64 の処理》有很好的例子。我简写如下:

Class Base64
    Private objCapiCom
 
    Private Sub Class_Initialize()
        Set objCapiCom = CreateObject("CAPICOM.Utilities")
    End Sub
 
    Private Sub Class_Terminate()
        Set objCapiCom = Nothing
    End Sub
 
    Public Function encode(str)
        encode = objCapiCom.Base64Encode(str)
    End Function
 
    Public Function decode(str)
        decode = objCapiCom.Base64Decode(str)
    End Function
End Class
 
' Set objBase64 = New Base64
' MsgBox objBase64.decode(objBase64.encode("Hello World"))
' Set objBase64 = Nothing

原文还介绍了如何对而进制文件进行Base64编解码,用到了ByteArrayToBinaryStringBinaryStringToByteArray方法:

<!--METADATA TYPE="TypeLib" UUID="{EF53050B-882E-4776-B643-EDA472E8E3F2}" -->
<%
    Call Response.AddHeader( "Content-Type", "text/html; Charset=shift_jis" )
 
    Set Stream = Server.CreateObject("ADODB.Stream")
    Set CAPIUtil = Server.CreateObject( "CAPICOM.Utilities" )
 
    Stream.Open
    Stream.Type = adTypeBinary
    Stream.LoadFromFile Server.MapPath( "sample.jpg" )
    strFile = CAPIUtil.ByteArrayToBinaryString( Stream.Read )
    Stream.Close
 
    strEncoded = CAPIUtil.Base64Encode( strFile )
 
    ' バイナリデータを通常文字列として処理
 
    strDecoded = CAPIUtil.Base64Decode( strEncoded )
 
    strFile2 = CAPIUtil.BinaryStringToByteArray( strDecoded )
 
    Stream.Open
    Stream.Type = adTypeBinary
    Stream.Write strFile2
    Stream.SaveToFile Server.MapPath("sample2.jpg"), _
        adSaveCreateOverWrite 
    Stream.Close
 
%>

关于Base64的其他实现办法,可以参考我前面的一篇文章《Base24、Base64编码的几种程序实现》

CAPICOM.HashedData

实现常用的哈希函数

这里主要参考了《CAPICOM.dll을 이용한 Classic ASP(VBScript)에서 MD5 암호화 적용하기》,用到了一个Unicode字符串转换为Byte字符串的函数UStr2Bstr,当然为了便于理解,我还找到了逆函数BStr2UStr

Function BStr2UStr(BStr)
    'Byte string to Unicode string conversion
    Dim lngLoop
    BStr2UStr = ""
    For lngLoop = 1 to LenB(BStr)
        BStr2UStr = BStr2UStr & Chr(AscB(MidB(BStr,lngLoop,1))) 
    Next
End Function
 
Function UStr2Bstr(UStr)
    'Unicode string to Byte string conversion
    Dim lngLoop
    Dim strChar
    UStr2Bstr = ""
    For lngLoop = 1 to Len(UStr)
        strChar = Mid(UStr, lngLoop, 1)
        UStr2Bstr = UStr2Bstr & ChrB(AscB(strChar))
    Next
End Function

比如常见的MD5实现代码如下:

Function MD5(str)
    Dim objCapiCom
    Set objCapiCom = CreateObject("CAPICOM.HashedData")
        objCapiCom.Algorithm = 3
        objCapiCom.Hash UStr2Bstr(str)
        MD5 = objCapiCom.Value
    Set objCapiCom = Nothing
End Function
 
' MsgBox MD5("123456")

同样的大家也许注意到了objCapiCom.Algorithm,属性3指明了所使用的哈西算法,主要的算法定义有以下列表,这些同样可以从MSDN中找到

Const CAPICOM_HASH_ALGORITHM_SHA1   = 0
Const CAPICOM_HASH_ALGORITHM_MD2    = 1
Const CAPICOM_HASH_ALGORITHM_MD4    = 2
Const CAPICOM_HASH_ALGORITHM_MD5    = 3
Const CAPICOM_HASH_ALGORITHM_SHA256 = 4
Const CAPICOM_HASH_ALGORITHM_SHA384 = 5
Const CAPICOM_HASH_ALGORITHM_SHA512 = 6

同Base64编码解码一样,哈希函数也可以对二进制数据进行操作,具体做法是直接使用Hash方法分块哈希二进制数据,具体可以参考Demon为我们提供的代码

Function md5_file(filename, raw_output)
    Dim HashedData, Utility, Stream
    Set HashedData = CreateObject("CAPICOM.HashedData")
    Set Utility = CreateObject("CAPICOM.Utilities")
    Set Stream = CreateObject("ADODB.Stream")
    HashedData.Algorithm = 3
    Stream.Type = 1
    Stream.Open
    Stream.LoadFromFile filename
    Do Until Stream.EOS
        HashedData.Hash Stream.Read(1024)
    Loop
    If raw_output Then
        md5_file = Utility.HexToBinary(HashedData.Value)
    Else
        md5_file = HashedData.Value
    End If
End Function
若无特别说明,本网站文章均为原创,原则上这些文章不允许转载,但是如果阁下是出于研究学习目的可以转载到阁下的个人博客或者主页,转载遵循创作共同性“署名-非商业性使用-相同方式共享”原则,请转载时注明作者出处谢绝商业性、非署名、采集站、垃圾站或者纯粹为了流量的转载。谢谢合作!
请稍后...

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*