- Версия AutoIt
- 3.3.14.5
- Версия
- 2.6
Позволяет просто, без использования криптографических библиотек, создавать защищенные реплики (клоны, различающиеся внешним видом) информации, пригодные для хранения напр. в INI файлах. С точки зрения надежности, - это механизм подобный двухпроходному шифрованию с приватным ключом, в котором количество неизвестных всегда больше количества возможных уравнений математической модели. Конечно, после публикации криптографическая стойкость оригинального механизма падает, но на то он и исходник - рыба, что бы вы могли внести свою "долю яда" для любой модели.
Функция выделена из моей очень старой рабочей.
Более подробное описание в комментах прикрепленного первого архива
Обновил до версии 2.5. Существенно улучшена криптостойкость шифра, - все основные моменты генерации теперь привязаны к приватному ключу. Уже недостаточно подобрать два временных ключа, хотя и это было бы непросто. Сравнив с предыдущей версией легко понять, где лучше встроить собственные "фишки". При смене версии старые шифры придется генерить заново.
2.6: учтены ошибки и усложнен механизм шифрования, передача всех символов с кодами от 1 до 255
3.0: в комментах различные типы шифрования, передача кодов ограничена пользовательским массивом (несовместима с 2.6), если все непечатные и неиспользуемые символы в массиве заменены, то дешифрование становится утомительным, по причине что все отклики читабельны. Не нарушайте законов - и ни кто не будет декомпилировать Вашу программу.
.
Код:
#cs ; V1.0
Syntax.: $password = pass_tran($pass_str,[$pass_key, [$word_lngth, $encrypt]])
Where..: <$pass_str> = Строка для шифрования/дешифрования, в зависимости от значения параметра <$encrypt>
<$pass_key> = Ключевая фраза (приватный ключ) шифрования/дешифрования, не менее 8 символов.
<$word_lngth> = Длина ЗАШИФРОВАННОГО рабочего пароля, чем длинее <$word_lngth> и <$pass_key>, тем сложнее подобрать ключ.
<$encrypt> = 1 ШИФРОВАТЬ пароль, 0 РАСШИФРОВАТЬ пароль (default)
Returns: Зашифрованная или расшифрованная версия строки, переданная в параметре <$pass_str>,
в зависимости от значения параметра <$encrypt>. Функция не возвращает ошибок.
#ce
;~ #cs Примеры:
$s_pass="Саня Масяня <sm12345@mail.ru>|AbCd_@12345"
$s_encr=pass_tran($s_pass, '', 20, 1)
$s_decr=pass_tran($s_encr)
MsgBox(0,"Test", "Исходный текст:"& @CRLF & $s_pass & @CRLF & @CRLF & "Шифрованный:" & @CRLF & $s_encr & @CRLF & @CRLF & "Дешифрованный:"& @CRLF & $s_decr & @CRLF & @CRLF & "***")
$s_encr=pass_tran($s_pass, 'Для примера: Key String!!!', 20, 1)
$s_decr=pass_tran($s_encr, 'Для примера: Key String!!!')
MsgBox(0,"Test", "Исходный текст:"& @CRLF & $s_pass & @CRLF & @CRLF & "Шифрованный:" & @CRLF & $s_encr & @CRLF & @CRLF & "Дешифрованный:"& @CRLF & $s_decr & @CRLF & @CRLF & "***")
$s_decr=pass_tran($s_encr, 'Для примера: Key String !!')
MsgBox(0,"Test", "Исходный текст:"& @CRLF & $s_pass & @CRLF & @CRLF & "Шифрованный:" & @CRLF & $s_encr & @CRLF & @CRLF & "Дешифрованный:"& @CRLF & $s_decr & @CRLF & @CRLF & "***")
;~ #ce
Func pass_tran($pass_str, $pass_key='', $word_lngth=0, $encrypt=0)
Local $wrk_string, $wrk_pass, $wrk_char, $wrk_key, $wrk_len, $offset, $ptr1, $ptr2, $dat1
Const $_mod=62 ;модуль транскриптора, предельно передаваемый/возвращаемый код 62*62=3844
Const $_masc=255 ;модуль размера таблицы символов 255-ASCII
$pass_str=StringStripWS($pass_str,1) ;+2
If Not $pass_str Then Return ""
If StringLen($pass_str)+1 > $word_lngth Then $word_lngth=StringLen($pass_str)+2
If $pass_key and StringLen($pass_key)>7 Then ; ключ короче 8 символов это что закрыть дверь на веревочку
$wrk_key = $pass_key
Else ; по умолчанию здесь может быть загружен фрагмент какого либо файла либо строка на ваше усмотрение
$wrk_key = "Enter Your private key string (or ASCII code string) as default, обязательно замените на собственный ключ !!!"
;~ $wrk_key = StringMid(FileRead("myfile.txt"),$x1,$x2) ; где $x1,$x2 - начало и размер выборки, напр: $x1=77, $x2=512
; в этом случае файл, сами понимаете, не должен редактироваться и содержать нулевых байтов
EndIf
IF $encrypt Then ; шифрование строки
$wrk_string = $pass_str
For $i=1 To $word_lngth-StringLen($pass_str)
$wrk_string&=" "
Next
$wrk_pass=''
$wrk_char=''
; --- конвертор реплик, случайный код ascii для символа смещения
$offset = Random(1,61,1) ;будет существовать 61 реплика шифра - до 255
$wrk_len=StringLen($pass_str)
$wrk_pass = chr($offset) ; Сохранить символ смещения как первый
FOR $i=1 TO $word_lngth
$wrk_char = StringMid($wrk_string,$i,1)
$wrk_char = CHR(MOD(ASC($wrk_char)+$offset,$_masc)+1)
$wrk_pass &= $wrk_char
$offset = ASC($wrk_char)
Next
$offset=0
For $j=2 To StringLen($wrk_pass)
$offset+=Asc(StringMid($wrk_pass,$j,1))
Next
$offset=mod($offset,$_masc)
$wrk_pass = CHR(MOD(Asc(StringMid($wrk_pass,1,1))+$offset,$_masc)+1)&StringMid($wrk_pass,2)
$wrk_string=$wrk_pass
; --- второй уровень, собственно шифрование - используются два "временных" ключа
$wrk_pass=""
$wrk_len=StringLen($wrk_key)
$ptr1=Int($wrk_len/2)
$ptr2=$ptr1+1
Local $aPC[StringLen($wrk_string)+1]
$aPC[0]=StringLen($wrk_string)
For $i=1 To $aPC[0]
$aPC[$i]=Asc(StringMid($wrk_string,$i,1))
$dat1=Asc(StringMid($wrk_key,$ptr1,1))
$aPC[$i]=BitXOR($aPC[$i],$dat1) ;1 элемент шифрования
;~ $aPC[$i]+=$dat1 ; или так, или так и так
$ptr1 = Mod($ptr1+$i+$dat1,$wrk_len)+1
$dat1=Asc(StringMid($wrk_key,$ptr2,1))
$aPC[$i]+=$dat1 ;2 элемент шифрования
$ptr2 = Mod($ptr2-$i-$dat1,$wrk_len)+1
If $ptr2<1 Then $ptr2 += $wrk_len
;~ if $i>1 Then $aPC[$i]=$aPC[$i]+$aPC[$i-1] ;тоже можно
Next
; --- Транскиптор в печатный вид
$wrk_pass=""
For $j=1 To $aPC[0] ;StringLen($wrk_string)
$outdat=""
for $i=1 to 2
if $i =1 Then
$dat1=Int($aPC[$j]/$_mod)+1
Else
$dat1=Mod($aPC[$j],$_mod)+1
EndIf
Switch $dat1
Case 1 To 26
$outdat&=Chr($dat1+64)
Case 27 To 36
$outdat&=Chr($dat1+48-27)
Case Else
$outdat&=Chr($dat1+97-37)
EndSwitch
Next
$wrk_pass&=$outdat
Next
$wrk_string=$wrk_pass
$dat1=StringLen($wrk_string)
$ptr1=0
$ptr2=0
$wrk_pass=''
FOR $i=1 TO $dat1 ; Разобрать символы из рабочей строки с перестановкой (устранение регулярности)
If mod($i,2) Then
$wrk_pass &= StringMid($wrk_string,$dat1-$ptr1,1)
$ptr1+=1
Else
$ptr2+=1
$wrk_pass &= StringMid($wrk_string,$ptr2,1)
EndIf
Next
ELSE ; расшифровка... все строго в обратном порядке, иначе до исходного текста не добраться
$ptr1=0
$ptr2=0
$dat1=StringLen($pass_str)
Local $aPS[$dat1+1]
$aPC=StringSplit($pass_str,"")
FOR $i=1 TO $aPC[0] ; обратная перестановка
If mod($i,2) Then
$aPS[$dat1-$ptr1] = $aPC[$i]
$ptr1+=1
Else
$ptr2+=1
$aPS[$ptr2] = $aPC[$i]
EndIf
Next
$wrk_string=""
For $i=1 To $dat1
$wrk_string&=$aPS[$i]
Next
; --- обратный трнскриптор
$dat1=StringLen($wrk_string)
Local $aPC[int($dat1/2)+1]
$aPC[0]=int($dat1/2)
$ptr1=0
$wrk_pass=""
for $j=1 to StringLen($wrk_string) Step 2
$outdat=0
$ptr1+=1
$wrk_char=StringMid($wrk_string,$j,2)
for $i=1 to 2
$dat1=Asc((StringMid($wrk_string,$j+$i-1,1)) ) ;-1)
Switch $dat1
Case 64 To 90
$outdat+=$dat1-65 ;1..26
Case 48 To 57
$outdat+=$dat1-48+26 ;27..36
Case Else
$outdat+=$dat1-97+36 ;37..
EndSwitch
if $i =1 Then $outdat=$outdat*$_mod
Next
$wrk_pass&=Chr($outdat)
$aPC[$ptr1]=$outdat
Next
$wrk_string=$wrk_pass
; --- дешифровка (и снова две собаки на рояле)
$wrk_pass=""
$outdat=""
$wrk_len=StringLen($wrk_key)
$ptr1=Int($wrk_len/2)
$ptr2=$ptr1+1
For $i=1 To $aPC[0]
$dat1=Asc(StringMid($wrk_key,$ptr2,1))
$aPC[$i]-=$dat1 ;вернуть 2 элемент шифрования
$ptr2 = Mod($ptr2-$i-$dat1,$wrk_len)+1
If $ptr2<1 Then $ptr2 += $wrk_len
$dat1=Asc(StringMid($wrk_key,$ptr1,1))
;~ $aPC[$i]-=$dat1
$aPC[$i]=BitXOR($aPC[$i],$dat1) ;вернуть 1 элемент шифрования
$ptr1 = Mod($ptr1+$i+$dat1,$wrk_len)+1
$outdat&=Chr($aPC[$i])
Next
; --- реставрация реплики
$offset=0
For $i=2 To StringLen($outdat)
$offset+=Asc(StringMid($outdat,$i,1))
Next
$dat1=Asc(StringMid($outdat,1,1))-mod($offset,$_masc)-1
If $dat1<0 Then $dat1+=$_masc ;
$outdat = CHR($dat1)&StringMid($outdat,2)
$offset = Asc(StringMid($outdat,1,1))
FOR $i=2 TO $aPC[0] ;$wrk_len
$wrk_char = StringMid($outdat,$i,1)
IF ASC($wrk_char) <= $offset Then
$dat1=$_masc+ASC($wrk_char)-$offset-1
ELSE
$dat1=ASC($wrk_char)-$offset-1
ENDIF
If Not $dat1 Then $dat1=$_masc
$wrk_pass &= Chr($dat1)
$offset = ASC($wrk_char)
Next
$wrk_pass = StringStripWS($wrk_pass,2) ;1 --- вуаля
ENDIF
RETURN $wrk_pass
EndFunc
Функция выделена из моей очень старой рабочей.
Более подробное описание в комментах прикрепленного первого архива
Сообщение автоматически объединено:
Обновил до версии 2.5. Существенно улучшена криптостойкость шифра, - все основные моменты генерации теперь привязаны к приватному ключу. Уже недостаточно подобрать два временных ключа, хотя и это было бы непросто. Сравнив с предыдущей версией легко понять, где лучше встроить собственные "фишки". При смене версии старые шифры придется генерить заново.
Код:
#cs ;V2.5 Vic58
Syntax.: $password = pass_tran($pass_str,[$pass_key, [$word_lngth, $encrypt]])
Where..: <$pass_str> = Строка для шифрования/дешифрования, в зависимости от значения параметра <$encrypt>
<$pass_key> = Ключевая фраза (приватный ключ) шифрования/дешифрования, не менее 8 символов.
<$word_lngth> = Длина ЗАШИФРОВАННОГО рабочего пароля, чем длинее <$word_lngth> и <$pass_key>, тем сложнее подобрать ключ.
<$encrypt> = 1 ШИФРОВАТЬ пароль, 0 РАСШИФРОВАТЬ пароль (default)
Returns: Зашифрованная или расшифрованная версия строки, переданная в параметре <$pass_str>,
в зависимости от значения параметра <$encrypt>. Функция не возвращает ошибок.
#ce
;~ #cs Примеры:
$s_pass="Саня Масяня <sm12345@mail.ru>|AbCde_@12345"
$s_encr=pass_tran($s_pass, '', 50, 1)
$s_decr=pass_tran($s_encr)
MsgBox(0,"Test", "Исходный текст:"& @CRLF & $s_pass & @CRLF & @CRLF & "Шифрованный:" & @CRLF & $s_encr & @CRLF & @CRLF & "Дешифрованный:"& @CRLF & $s_decr & @CRLF & @CRLF & "***")
$s_encr=pass_tran($s_pass, 'Для примера: Key String!!!', 0, 1)
$s_decr=pass_tran($s_encr, 'Для примера: Key String!!!')
MsgBox(0,"Test", "Исходный текст:"& @CRLF & $s_pass & @CRLF & @CRLF & "Шифрованный:" & @CRLF & $s_encr & @CRLF & @CRLF & "Дешифрованный:"& @CRLF & $s_decr & @CRLF & @CRLF & "***")
$s_decr=pass_tran($s_encr, 'Для примера: Key String !!')
MsgBox(0,"Test", "Исходный текст:"& @CRLF & $s_pass & @CRLF & @CRLF & "Шифрованный:" & @CRLF & $s_encr & @CRLF & @CRLF & "Дешифрованный:"& @CRLF & $s_decr & @CRLF & @CRLF & "***")
;~ #ce
Func pass_tran($pass_str, $pass_key='', $word_lngth=0, $encrypt=0)
Local $wrk_string, $wrk_pass, $wrk_char, $wrk_key, $wrk_len, $offset, $ptr1, $ptr2, $dat1
Const $_mod=62 ;модуль транскриптора, предельно передаваемый/возвращаемый код 62*62=3844
Const $_masc=255 ;модуль размера таблицы символов: 255-ASCII
$pass_str=StringStripWS($pass_str,3)
If Not $pass_str Then Return ""
If StringLen($pass_str)+1 > $word_lngth Then $word_lngth=StringLen($pass_str)+2
If $pass_key and StringLen($pass_key)>7 Then ; ключ короче 8 символов это что закрыть дверь на веревочку
$wrk_key = $pass_key
Else ; по умолчанию здесь может быть загружен фрагмент какого либо файла либо строка на ваше усмотрение
$wrk_key = "Enter Your private key string (or ASCII code string) as default, обязательно замените на собственный ключ !!!"
;~ $wrk_key = StringMid(FileRead("myfile.txt"),$x1,$x2) ; где $x1,$x2 - начало и размер выборки, напр: $x1=77, $x2=512
; в этом случае файл, сами понимаете, не должен редактироваться и содержать нулевых байтов
EndIf
IF $encrypt Then ; шифрование строки
$wrk_string = $pass_str
For $i=1 To $word_lngth-StringLen($pass_str)
$wrk_string=" " & $wrk_string
Next
; --- конвертор реплик (1 проход), случайный код ascii для символа смещения
$offset = Random(1,61,1) ;будет существовать 61 реплика шифра - до 255
$wrk_len=StringLen($pass_str)
$wrk_pass = chr($offset) ; Сохранить символ смещения как первый
FOR $i=1 TO $word_lngth ; соберем реплику с добавлением зависимости от ключа
$wrk_char = CHR(MOD(ASC(StringMid($wrk_string,$i,1))+$offset+ASC(StringMid($wrk_key,MOD($offset+$i,StringLen($wrk_key)),1))+$i,$_masc)+1)
$wrk_pass &= $wrk_char
$offset = ASC($wrk_char)
Next
$offset=0
For $j=2 To StringLen($wrk_pass)
$offset+=Asc(StringMid($wrk_pass,$j,1))
Next
$offset=mod($offset,$_masc)
$wrk_string = StringTrimLeft($wrk_pass,1) & CHR(MOD(Asc(StringMid($wrk_pass,1,1))+$offset,$_masc)+1)
; --- второй уровень, собственно шифрование - используются два "временных" виртуальных ключа, два прохода
$wrk_pass=""
$wrk_len=StringLen($wrk_key)
$wrk_char=Asc(StringMid($wrk_key,$wrk_len-1))
$ptr1=Int($wrk_len/2) ; Кто сказал что старт для виртуальных ключей надо начинать с середины ключя?
$ptr2=$ptr1+1 ; стартовую позицию лучше найти в самом ключе из соотношения какиз либо частей
Local $aPC[StringLen($wrk_string)+1]
$aPC[0]=StringLen($wrk_string)
For $i=1 To $aPC[0]
$dat1=Asc(StringMid($wrk_key,$ptr1,1))
$aPC[$i]=BitXOR(Asc(StringMid($wrk_string,$i,1)),$dat1) ;1 элемент шифрования
$ptr1 = Mod($ptr1+$i+$dat1,$wrk_len)+1
$dat1=Asc(StringMid($wrk_key,$ptr2,1))
$ptr2 = Mod($ptr2-$i-$dat1,$wrk_len)+1
$aPC[$i]+=BitXOR($dat1,Mod($wrk_char+$i,$_masc)) ;2 элемент шифрования, предельный разброс от 0 до 510 на выходе
If $ptr2<1 Then $ptr2 += $wrk_len ;транскриптор позволяет до 3800, подумайте сами, чтоб ещё, по тяму надо.
$wrk_char=$aPC[$i]
Next
; --- Транскиптор в печатный вид
$wrk_pass=""
For $j=1 To $aPC[0]
$outdat=""
for $i=1 to 2
if $i =1 Then
$dat1=Int($aPC[$j]/$_mod)+1
Else
$dat1=Mod($aPC[$j],$_mod)+1
EndIf
Switch $dat1
Case 1 To 26
$outdat&=Chr($dat1+64)
Case 27 To 36
$outdat&=Chr($dat1+48-27)
Case Else
$outdat&=Chr($dat1+97-37)
EndSwitch
Next
$wrk_pass&=$outdat
Next
$wrk_string=$wrk_pass
$dat1=StringLen($wrk_string)
$ptr1=0
$ptr2=0
$wrk_pass=''
FOR $i=1 TO $dat1 ; Разберем символы из рабочей строки с перестановкой по ключу (устранение регулярности)
If mod(Asc(StringMid($wrk_key,Mod($i,StringLen($wrk_key))+1,1)),2) Then
$wrk_pass &= StringMid($wrk_string,$dat1-$ptr1,1)
$ptr1+=1
Else
$ptr2+=1
$wrk_pass &= StringMid($wrk_string,$ptr2,1)
EndIf
Next
ELSE ; расшифровка... все строго в обратном порядке, иначе до исходного текста не добраться
$ptr1=0
$ptr2=0
$dat1=StringLen($pass_str)
Local $aPS[$dat1+1]
$aPC=StringSplit($pass_str,"")
FOR $i=1 TO $aPC[0] ; обратная перестановка
If mod(Asc(StringMid($wrk_key,Mod($i,StringLen($wrk_key))+1,1)),2) Then
$aPS[$dat1-$ptr1] = $aPC[$i]
$ptr1+=1
Else
$ptr2+=1
$aPS[$ptr2] = $aPC[$i]
EndIf
Next
$wrk_string=""
For $i=1 To $dat1
$wrk_string&=$aPS[$i]
Next
; --- обратный трнскриптор
$dat1=StringLen($wrk_string)
Local $aPC[Int($dat1/2)+1]
$aPC[0]=int($dat1/2)
$ptr1=0
$wrk_pass=""
for $j=1 to StringLen($wrk_string) Step 2
$outdat=0
$ptr1+=1
$wrk_char=StringMid($wrk_string,$j,2)
for $i=1 to 2
$dat1=Asc((StringMid($wrk_string,$j+$i-1,1)) ) ;-1)
Switch $dat1
Case 64 To 90
$outdat+=$dat1-65 ;1..26
Case 48 To 57
$outdat+=$dat1-48+26 ;27..36
Case Else
$outdat+=$dat1-97+36 ;37..
EndSwitch
if $i =1 Then $outdat=$outdat*$_mod
Next
$wrk_pass&=Chr($outdat)
$aPC[$ptr1]=$outdat
Next
$wrk_string=$wrk_pass
; --- дешифровка (и снова "две собаки на рояле")
$wrk_pass=""
$outdat=""
$wrk_len=StringLen($wrk_key)
$wrk_char=Asc(StringMid($wrk_key,$wrk_len-1))
$ptr1=Int($wrk_len/2)
$ptr2=$ptr1+1
For $i=1 To $aPC[0]
$dat1=Asc(StringMid($wrk_key,$ptr2,1))
$ptr2 = Mod($ptr2-$i-$dat1,$wrk_len)+1
$offset = $aPC[$i]
$aPC[$i]-=BitXOR($dat1,Mod($wrk_char+$i,$_masc)) ;вернуть 2 элемент шифрования
If $ptr2<1 Then $ptr2 += $wrk_len
$dat1=Asc(StringMid($wrk_key,$ptr1,1))
$aPC[$i]=BitXOR($aPC[$i],$dat1) ;вернуть 1 элемент шифрования
$ptr1 = Mod($ptr1+$i+$dat1,$wrk_len)+1
$outdat&=Chr($aPC[$i])
$wrk_char=$offset
Next
; --- реставрация реплики
$outdat=Chr($aPC[$aPC[0]]) & StringTrimRight($outdat,1)
$offset=0
For $i=2 To StringLen($outdat)
$offset+=Asc(StringMid($outdat,$i,1))
Next
$dat1=Asc(StringMid($outdat,1,1))-mod($offset,$_masc)-1
If $dat1<0 Then $dat1+=$_masc ;
$outdat = CHR($dat1)&StringMid($outdat,2)
$offset = Asc(StringMid($outdat,1,1)) ;1 символ смещения от Random()
; FOR $i=2 TO $aPC[0] ; начнем со 2-го, "делового"
FOR $i=2 TO StringLen($outdat) ;$aPC[0] ; начнем со 2-го, "делового"
$wrk_char = StringMid($outdat,$i,1)
$dat1=ASC($wrk_char)-Mod($offset+$i+ASC(StringMid($wrk_key,MOD($offset+$i-1,$wrk_len),1)),$_masc)
If $dat1<1 Then $dat1+=$_masc
$wrk_pass &= Chr($dat1)
$offset = ASC($wrk_char)
Next
$wrk_pass = StringStripWS($wrk_pass,3) ;1 --- вуаля
ENDIF
RETURN $wrk_pass
EndFunc
2.6: учтены ошибки и усложнен механизм шифрования, передача всех символов с кодами от 1 до 255
3.0: в комментах различные типы шифрования, передача кодов ограничена пользовательским массивом (несовместима с 2.6), если все непечатные и неиспользуемые символы в массиве заменены, то дешифрование становится утомительным, по причине что все отклики читабельны. Не нарушайте законов - и ни кто не будет декомпилировать Вашу программу.
.
- Автор
- Vic58
Вложения
Последнее редактирование: