Функция расшифровки дает неправильный результат с помощью специальных символов - PullRequest
3 голосов
/ 10 февраля 2020

Я создаю функцию шифрования / дешифрования в VBScript / Classi c 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

1 Ответ

0 голосов
/ 02 апреля 2020

Не знаю, нужно ли вам это исправить, но все вышеперечисленное объясняется тем, что hex () возвращает строку длиннее 2 для любого десятичного числа свыше 255:

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

т.е. когда исходная строка + соль превышает 255 (10)

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

, тогда "For y=1 To valLen Step 2" будет принимать только "13" из "132", что приведет к неправильному дешифрованию.

Зависит от необходимость, это может быть «исправлено», например, путем проверки, если зашифрованный код больше 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 не нужно использовать AscW () / ChrW (), которые являются Unicode Speci c.

Другой подход заключается в замене шестнадцатеричного на что-то более «стабильное», то есть base32. Взяв пример кода из Classi c ASP / VBScript реализации кодирования Base32 Крокфорда , ваш код может выглядеть как

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
...