vbscript - 解密函数给出带有特殊字符的错误结果

标签 vbscript asp-classic

我正在用 VBScript/Classic ASP 构建加密/解密函数。 只要要加密/解密的字符串不包含特殊字符,这一切都有效。

' str = "Bayern München"
' key = "ab34ehyd67hy6752daskjh"

Function EncryptString(val, key)

    valLen = Len(val)
    keyLen = Len(key)
    keyPos = 1
    newVal = ""
    revVal = val

    For x = 1 To valLen
        calc = AscW(Mid(revVal, x, 1)) + AscW(Mid(key, keyPos, 1))
        'Response.Write ":" & AscW(Mid(revVal, x, 1)) & " + " & AscW(Mid(key, keyPos, 1)) & " = " & calc & "<br />"
        newVal = newVal & Hex(calc)
        keyPos = keyPos + 1
        If keyPos > keyLen Then keyPos = 1
    Next

    EncryptString = newVal

End Function

Function DecryptString(val, key)

    ' The workaround - start
    For i = 160 To 255
        val = Replace(val, Chr(i), "&#" & i & ";")
    Next
    ' The workaround - end

    valLen = Len(val)
    keyLen = Len(key)
    keyPos = 1
    newVal = ""
    revVal = val
    chrVal = ""

    ' I suspect this to be the error
    For y = 1 To valLen Step 2
        chrVal = chrVal & ChrW("&h" & Mid(revVal, y, 2))
    Next

    For x = 1 To Len(chrVal)
        calc = AscW(Mid(chrVal, x, 1)) - AscW(Mid(key, keyPos, 1))
        'Response.Write "::" & AscW(Mid(chrVal, x, 1)) & " - " & AscW(Mid(key, keyPos, 1)) & " = " & calc & "<br />"
        newVal = newVal & ChrW(calc)
        keyPos = keyPos + 1
        If keyPos > keyLen Then keyPos = 1
    Next

    DecryptString = newVal

End Function

如果我对字符串“Bayern München”进行加密,然后对加密字符串调用 DecryptString 函数,它会返回 Bayern M?À?vU?

如果我输出数据(示例中的 Response.Write),解密函数返回字符 ü 的负数,所以我做错了什么 - 但是什么?

系统编码为Windows-1252。

更新:

我在 DecryptString 函数中做了这个解决方法。我不确定它是否涵盖了所有可能的问题,但从我目前的测试来看它确实涵盖了:

For i = 160 To 255
    val = Replace(val, Chr(i), "&#" & i & ";")
Next

最佳答案

不知道你是否还需要修复它,但以上都是因为hex()对于任何超过 255 的小数,返回一个长于 2 的字符串:

(255)10 = (FF)16
(256)10 = (100)16 

即当原始字符串 + salt 超过 255(10)

("ü" 252) + ("6" 54) = 252+54 = 306(10)=132(16) (3 characters long)

然后 “For y=1 To valLen Step 2” 将只取“132”中的“13”,这将导致不正确的解密。

根据需要,可以“固定”,例如检查加密代码是否超过255,如果为真,则不加盐:

Function EncryptString(val, key)

...
'newVal = newVal & Hex(calc) <-- replace this by following code
if calc > 255 then 
   newVal = newVal & "01" & Hex(Asc(Mid(revVal, x, 1))) ' no salt
else
   newVal = newVal & Hex(calc)
end if

其中“01”只是一个“信号”字符,表示下一个字符将不含盐。

分别是

Function DecryptString(val, key)
...
'calc = Asc(Mid(chrVal, x, 1)) - Asc(Mid(key, keyPos, 1))
if Asc(Mid(chrVal, x, 1))=1 then 'determine "signal"
   ignorenext = true 'flag that next char has no salt
else
   if ignorenext then
      calc = Asc(Mid(chrVal, x, 1)) 'no salt
      ignorenext = false
   else 
       calc = Asc(Mid(chrVal, x, 1)) - Asc(Mid(key, keyPos, 1))
   end if 

   newVal = newVal & Chr(calc)
   keyPos = keyPos + 1
   If keyPos > keyLen Then keyPos = 1
end if

请注意,对于 Windows-1252,无需使用特定于 unicode 的 AscW()/ChrW()。

另一种方法是将十六进制替换为更“稳定”的东西,即 base32。从 Classic ASP/VBScript implementation of Crockford's Base32 Encoding 中获取示例代码你的代码看起来像

Function EncryptString(val, key)

    valLen = Len(val)
    keyLen = Len(key)
    keyPos = 1
    newVal = ""
    revVal = val

    For x = 1 To valLen
        calc = Asc(Mid(revVal, x, 1)) + Asc(Mid(key, keyPos, 1)) 
        newVal = newVal & ToBase32(calc) 
        keyPos = keyPos + 1
        If keyPos > keyLen Then keyPos = 1
    Next

    EncryptString = ucase(newVal)

End Function

Function DecryptString(val, key)

    valLen = Len(val)
    keyLen = Len(key)
    keyPos = 1
    newVal = ""
    revVal = val
    chrVal = ""

    For y = 1 To valLen Step 2 
        chrVal = chrVal & fromBase32(Mid(revVal, y, 2))  
        calc = fromBase32(Mid(revVal, y, 2)) - Asc(Mid(key, keyPos, 1))   
        newVal = newVal & Chr(calc) 
        keyPos = keyPos + 1
        If keyPos > keyLen Then keyPos = 1  
    Next

    DecryptString = newVal

End Function

关于vbscript - 解密函数给出带有特殊字符的错误结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60151047/

相关文章:

Vbscript 修剪函数

excel - 生成多个 excel

vbscript - 使用 Response.BinaryWrite 显示 JPEG

database - 经典 ASP - 使用 Windows 身份验证的 SQL Server 2008 连接字符串

javascript - HTML 页面显示 vbscript 代码,而不是运行脚本。为什么?

css - 以模态形式验证

vbscript - 以编程方式测量打印作业时间

windows - 如何将 .bat 文件制作成 GUI .exe?

sql-server - 赢得身份验证 NT 权限\匿名登录

asp.net - 从经典 ASP 调用需要 .NET 类型的 .NET 函数