首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

VBScript 十六進制異或加密實現:二進制檔案流式處理、金鑰擴展與 XML DOM 編碼轉換

     編輯:更多程式設計知識

基於 VBScript 實現的對稱加密工具,採用十六進制編碼 + 異或 (XOR) 流加密模式,支援任意二進制檔案(圖片、文件、執行檔),透過 ADODB.Stream + XML DOM 實現二進制↔十六進制無損轉換。附帶完整加密/解密驗證流程。

一、核心設計決策

決策點選擇理由
編碼格式十六進制可列印、無字元集問題、XML DOM 原生支援 bin.hex
加密模式XOR 流加密 (Vernam Cipher 變體)實現簡單、加解密對稱、無需填充
金鑰處理循環重複 (Repeating Key)支援任意長度金鑰、無需金鑰擴展算法
二進制讀寫ADODB.Stream (Type=1)Windows 內建、高效、支援大檔案
十六進制轉換XML DOM Node (dataType="bin.hex")純腳本無需外部元件、自動處理編碼

二、完整腳本代碼

' === XORCrypt.vbs ===
Option Explicit

Dim Key, startTime
Key = "www-enun-net" ' 金鑰:建議非純數字,長度 8-32 字元

' === 測試流程 ===
WScript.Echo Now & ", 加密開始"
Dim plainData, encData
plainData = ReadBinary("test.jpg")
encData = EncryptHex(plainData)
WriteBinary "E_test.jpg", encData
WScript.Echo Now & ", 加密完成"

WScript.Echo Now & ", 解密開始"
Dim decData
decData = ReadBinary("E_test.jpg")
Dim plainRestored
plainRestored = DecryptHex(decData)
WriteBinary "U_test.jpg", plainRestored
WScript.Echo Now & ", 解密完成"

' === 二進制檔案讀取:檔案 → 十六進制字串 ===
Function ReadBinary(filePath)
    Dim stream, xmlDoc, node
    Set xmlDoc = CreateObject("Microsoft.XMLDOM")
    Set node = xmlDoc.CreateElement("binary")
    node.DataType = "bin.hex"
    
    Set stream = CreateObject("ADODB.Stream")
    stream.Type = 1 ' adTypeBinary
    stream.Open
    stream.LoadFromFile filePath
    node.NodeTypedValue = stream.Read
    stream.Close
    
    ReadBinary = node.Text
    Set node = Nothing: Set stream = Nothing: Set xmlDoc = Nothing
End Function

' === 十六進制字串寫入檔案 ===
Function WriteBinary(filePath, hexStr)
    Dim stream, xmlDoc, node
    Set xmlDoc = CreateObject("Microsoft.XMLDOM")
    Set node = xmlDoc.CreateElement("binary")
    node.DataType = "bin.hex"
    node.Text = hexStr
    
    Set stream = CreateObject("ADODB.Stream")
    stream.Type = 1
    stream.Open
    stream.Write node.NodeTypedValue
    stream.SaveToFile filePath, 2 ' adSaveCreateOverWrite
    stream.Close
    
    Set stream = Nothing: Set node = Nothing: Set xmlDoc = Nothing
End Function

' === 加密:十六進制字串 → 異或 → 十六進制字串 ===
Function EncryptHex(hexStr)
    Dim keyBytes, keyLen, i, j, byteVal, keyByte, encByte
    hexStr = UCase(hexStr)
    keyLen = Len(Key)
    
    ' 預計算金鑰位元組陣列 (ASCII 碼)
    ReDim keyBytes(keyLen - 1)
    For i = 0 To keyLen - 1
        keyBytes(i) = Asc(Mid(Key, i + 1, 1))
    Next
    
    ' 逐字節處理:十六進制字串每 2 字元 = 1 byte
    Dim result, hexByte
    result = ""
    For i = 1 To Len(hexStr) Step 2
        hexByte = Mid(hexStr, i, 2)
        byteVal = CByte("&H" & hexByte)
        keyByte = keyBytes(((i - 1) / 2) Mod keyLen)
        encByte = byteVal Xor keyByte
        result = result & Right("0" & Hex(encByte), 2) ' 確保 2 位十六進制
    Next
    EncryptHex = result
End Function

' === 解密:同加密邏輯 (XOR 可逆) ===
Function DecryptHex(hexStr)
    Dim keyBytes, keyLen, i, byteVal, keyByte, decByte
    hexStr = UCase(hexStr)
    keyLen = Len(Key)
    
    ReDim keyBytes(keyLen - 1)
    For i = 0 To keyLen - 1
        keyBytes(i) = Asc(Mid(Key, i + 1, 1))
    Next
    
    Dim result, hexByte
    result = ""
    For i = 1 To Len(hexStr) Step 2
        hexByte = Mid(hexStr, i, 2)
        byteVal = CByte("&H" & hexByte)
        keyByte = keyBytes(((i - 1) / 2) Mod keyLen)
        decByte = byteVal Xor keyByte
        result = result & Right("0" & Hex(decByte), 2)
    Next
    DecryptHex = result
End Function

三、關鍵算法細節

1. 十六進制字串處理邏輯

  • 輸入:"FF00AB" (3 bytes: 0xFF, 0x00, 0xAB)
  • 迴圈:Step 2 每次取 2 字元
  • CByte("&H" & hexByte) 將十六進制字串轉 Byte 數值
  • XOR 運算後 Hex(decByte) 轉回十六進制,Right("0" & ..., 2) 補零

2. 金鑰索引計算

' i 為十六進制字串位置 (1-based, step 2)
' byteIndex = (i - 1) / 2  (0-based byte 索引)
' keyIndex = byteIndex Mod keyLen
' 等價於:每處理 1 個 byte,金鑰索引 +1,循環使用

3. XML DOM bin.hex 魔法

' 寫入二進制 → 十六進制
node.DataType = "bin.hex"
node.NodeTypedValue = binaryData  ' Variant(Byte())
hexStr = node.Text

' 十六進制 → 二進制
node.DataType = "bin.hex"
node.Text = hexStr
binaryData = node.NodeTypedValue  ' 返回 Variant(Byte())

四、安全性分析與局限

定性:流加密,但金鑰重複使用 → 多表代換密碼,非一次性密碼本 (OTP)。
弱點:

  • 已知明文攻擊:若攻擊者知部分明文,可推導金鑰流片段
  • 金鑰重複:長檔案中金鑰循環重複,統計分析可破解
  • 無完整性驗證:密文修改解密後無法檢測
  • 無認證:無法防止中間人竄改

適用場景:輕度混淆、非敏感資料臨時保護、教學演示。
嚴禁場景:機密資料、傳輸加密、長期儲存保護、任何合規要求場景。

五、效能與檔案大小限制

檔案大小十六進制字串長度記憶體佔用處理時間 (參考)
1 MB2 MB~10 MB< 1 秒
10 MB20 MB~100 MB~5 秒
100 MB200 MB~1 GB~60 秒
硬性限制:VBScript 字串長度上限 ~2GB (實際受限於 32 位元進程空間 ~1.5GB)。建議 單檔 < 50 MB。大檔案需分塊處理或改用串流式加密 (AES-GCM)。

六、改進版:分塊串流加密 (降低記憶體)

Function EncryptFile_Streaming(srcPath, dstPath, key, Optional chunkSize = 1048576)
    Dim srcStream, dstStream, xmlDoc, node, buffer, hexStr, encHex, i, keyBytes, keyLen
    
    ' 初始化金鑰
    keyLen = Len(key)
    ReDim keyBytes(keyLen - 1)
    For i = 0 To keyLen - 1: keyBytes(i) = Asc(Mid(key, i + 1, 1)): Next
    
    Set srcStream = CreateObject("ADODB.Stream")
    srcStream.Type = 1: srcStream.Open: srcStream.LoadFromFile srcPath
    
    Set dstStream = CreateObject("ADODB.Stream")
    dstStream.Type = 1: dstStream.Open
    
    Set xmlDoc = CreateObject("Microsoft.XMLDOM")
    Set node = xmlDoc.CreateElement("binary")
    node.DataType = "bin.hex"
    
    Dim byteIndex, keyByte, byteVal, encByte, hexByte
    byteIndex = 0
    
    Do Until srcStream.EOS
        buffer = srcStream.Read(chunkSize)
        node.NodeTypedValue = buffer
        hexStr = node.Text
        
        ' 加密十六進制字串
        encHex = ""
        For i = 1 To Len(hexStr) Step 2
            hexByte = Mid(hexStr, i, 2)
            byteVal = CByte("&H" & hexByte)
            keyByte = keyBytes(byteIndex Mod keyLen)
            encByte = byteVal Xor keyByte
            encHex = encHex & Right("0" & Hex(encByte), 2)
            byteIndex = byteIndex + 1
        Next
        
        ' 寫入加密後二進制
        node.Text = encHex
        dstStream.Write node.NodeTypedValue
    Loop
    
    dstStream.SaveToFile dstPath, 2
    srcStream.Close: dstStream.Close
End Function

七、現代替代:PowerShell AES-GCM 一鍵加密

# 加密
$key = [System.Text.Encoding]::UTF8.GetBytes("My32ByteKeyForAES256GCM!!!!")
$plain = [IO.File]::ReadAllBytes("test.jpg")
$aes = [System.Security.Cryptography.AesGcm]::new($key)
$nonce = [System.Security.Cryptography.RandomNumberGenerator]::GetBytes(12)
$tag = New-Object byte[] 16
$cipher = New-Object byte[] $plain.Length
$aes.Encrypt($nonce, $plain, $cipher, $tag, [System.Text.Encoding]::UTF8.GetBytes("context"))
[IO.File]::WriteAllBytes("test.enc", $nonce + $cipher + $tag)

# 解密
$data = [IO.File]::ReadAllBytes("test.enc")
$nonce = $data[0..11]
$cipher = $data[12..($data.Length-17)]
$tag = $data[($data.Length-16)..($data.Length-1)]
$aes.Decrypt($nonce, $cipher, $tag, [System.Text.Encoding]::UTF8.GetBytes("context"), $plain)
[IO.File]::WriteAllBytes("test_dec.jpg", $plain)
總結:VBScript XOR 十六進制加密展示了腳本語言處理二進制資料的經典技巧 (ADODB.Stream + XML DOM),但其密碼學強度極低。理解其原理有助於掌握流加密基礎、十六進制編碼、COM 互操作,生產環境請毫不猶豫選用 AES-GCM / ChaCha20-Poly1305 等現代認證加密算法。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved