PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » PureBasic для Windows » Кодировать / декодировать файл


Кодировать / декодировать файл

Сообщений 1 страница 20 из 20

1

На оф.форуме выложил код небольшой прожки с GUI.
https://i.imgur.com/RKKtgiv.png
Ранее я писал это на AutoIt3, просто переписал на PureBasic в связи с поднятием темы шифрования на оф.форуме.
Из нового, в AutoIt3 была функция с паролем, а тут надо было пароль 16 байт и вектор 16 байт, пришлось писать функцию, которая имеет неявный пароль генерируемый рандомом с RandomSeed, а поверх "рандома" писать пароль из поля в GUI, если будет не хватать длины, она будет дополнена "рандомом" до 16 байт. Перечитал справку, 16 байт для 128 битного ключа, так что мне надо либо битность исправить, либо  увеличить ключ, но это уже мелочи, при тесте всё работает как есть.

0

2

AZJIO написал(а):

На оф.форуме выложил код небольшой прожки с GUI.

Файл читается целиком в память. Если он имеет большой объем может не получится выделить столько памяти. Лучше читать частями, скажем по 10 МБ и выполнять шифрование функциями StartAESCipher(), AddCipherBuffer() и FinishCipher().

AZJIO написал(а):

Из нового, в AutoIt3 была функция с паролем, а тут надо было пароль 16 байт и вектор 16 байт, пришлось писать функцию, которая имеет неявный пароль генерируемый рандомом с RandomSeed, а поверх "рандома" писать пароль из поля в GUI

Я не знаю как устроен AES в AutoIt3. Может он работает в режиме Electronic CodeBook при котором InitializationVector не требуется, но качество шифрования ниже.

С паролем можно сделать так.
Без InitializationVector

Код:
UseSHA1Fingerprint()

; Шифруем строку
String$ = "Здравствуйте, это тест для AES"
Pass.s = "1234" ; Пароль шифрования.

StringMemorySize = StringByteLength(String$) + SizeOf(Character)
*CipheredString = AllocateMemory(StringMemorySize)   
*DecipheredString = AllocateMemory(StringMemorySize) 

*Key = Ascii(StringFingerprint(Pass, #PB_Cipher_SHA1, 0, #PB_Unicode))
ShowMemoryViewer(*Key, MemorySize(*Key))

If AESEncoder(@String$, *CipheredString, StringByteLength(String$), *Key, 256, 0, #PB_Cipher_ECB)
  Debug "Ciphered: "+PeekS(*CipheredString) ; Предупреждение, это остановится на первом нулевом байте, только для демонстрации.
  
  AESDecoder(*CipheredString, *DecipheredString, StringByteLength(String$), *Key, 256, 0, #PB_Cipher_ECB)
  Debug "Deciphered: "+PeekS(*DecipheredString)
EndIf

FreeMemory(*CipheredString)
FreeMemory(*DecipheredString)
FreeMemory(*Key)

С InitializationVector

Код:
UseSHA1Fingerprint()
UseMD5Fingerprint()

; Шифруем строку
String$ = "Здравствуйте, это тест для AES"
Pass.s = "1234" ; Пароль шифрования.

StringMemorySize = StringByteLength(String$) + SizeOf(Character)
*CipheredString = AllocateMemory(StringMemorySize)   
*DecipheredString = AllocateMemory(StringMemorySize) 

*Key = Ascii(StringFingerprint(Pass, #PB_Cipher_SHA1, 0, #PB_Unicode))
*InitializationVector = Ascii(StringFingerprint(Pass, #PB_Cipher_MD5, 0, #PB_Unicode))
If AESEncoder(@String$, *CipheredString, StringByteLength(String$), *Key, 256, *InitializationVector, #PB_Cipher_CBC)
  Debug "Ciphered: "+PeekS(*CipheredString) ; Предупреждение, это остановится на первом нулевом байте, только для демонстрации.
  
  AESDecoder(*CipheredString, *DecipheredString, StringByteLength(String$), *Key, 256, *InitializationVector, #PB_Cipher_CBC)
  Debug "Deciphered: "+PeekS(*DecipheredString)
EndIf

FreeMemory(*CipheredString)
FreeMemory(*DecipheredString)
FreeMemory(*Key)
FreeMemory(*InitializationVector)

Здесь используется ascii строка хеша, а лучше перевести в бинарные данные, заменив SHA1 на SHA2 или SHA3 с 256 битным результатом.

0

3

Пётр
С SHA3 более проще. Была идея, если открыть путь, то зашифровать все файлы в папке. И добавить поддержку ком.строки, чтобы в конт.меню проводника можно было добавить. Про открывать блоками я знал, в AutoIt3 так и делал, но для MD5.

0

4

Чем вас не устроил "Исключающее или"?! Там можно для каждого файла гонять ключ в виде файла и получать результат.

0

5

У Aes уровень шифрования выше.

0

6

Код:
InputFile$=OpenFileRequester("Выберите файл для шифровки/дешифровки.","","",0)
InputFile=ReadFile(#PB_Any,InputFile$)
If InputFile=0:End:EndIf
KeyFile$=OpenFileRequester("Выберите файл-ключ.","","",0)
KeyFile=ReadFile(#PB_Any,KeyFile$)
If KeyFile=0:End:EndIf
*Key.Ascii=AllocateMemory(Lof(KeyFile))
If	ReadData(KeyFile,*Key,Lof(KeyFile))<>Lof(KeyFile):End:EndIf
OutputFile$=SaveFileRequester("Выберите файл-результат.","","",0)
OutputFile=CreateFile(#PB_Any,OutputFile$)
If OutputFile=0:End:EndIf
*k.Ascii=*Key
*Overflow=*k+Lof(KeyFile)
While Eof(InputFile)=0
	WriteAsciiCharacter(OutputFile,ReadAsciiCharacter(InputFile)!*k\a)
	*k+SizeOf(Ascii)
	If *k=*Overflow:*k=*Key:EndIf
	Wend

Не знаю... Что-то подобное я уже писал, вот и набросал то чё помню. Принцип простой, но для ключа надо выделять память. Можно конечно и из файла напрямую читать и бегать до начала файла, но так-быстрее.

0

7

PSY написал(а):

"Исключающее или"?!

Я и так знал, что степень защищенности максимальная, даже закон у нас есть проги шифрования с ключом не выше 128, иначе даже супер комп не расшифрует. Так на хабре статья, что шифрование блоками и предыдущий блок содержит ключ возможно вектор это и есть он для следующего блока, то есть не имея какой то части невозможно расшифровать последующее. Исключающее или это уровень детсада.

0

8

Зато можно просто выбрать входной файл, выбрать файл-ключ например изображение(щёлкнуть "фотку") и ей шифрануть чё хочешь. Работает же, Там даже больше уровня детского сада - если размер ключа равен размеру входного файла.

0

9

Код:
ReadFile(0,OpenFileRequester("Select input.","","",0))
ReadFile(1,OpenFileRequester("Select key.","","",0))
CreateFile(2,SaveFileRequester("Select output.","","",0))
While Eof(0)=0
	WriteAsciiCharacter(2,ReadAsciiCharacter(0)!ReadAsciiCharacter(1))
	If Eof(1)=0:FileSeek(1,0):EndIf:Wend

С минимальным потреблением памяти то есть ключ-файл быть может любой длины. Всё зависит только от накопителя и его размера. Сам воспользовался и не пожалел.

0

10

PSY написал(а):

Зато можно просто выбрать входной файл, выбрать файл-ключ например изображение(щёлкнуть "фотку") и ей шифрануть чё хочешь. Работает же, Там даже больше уровня детского сада - если размер ключа равен размеру входного файла.

Если используется XOR и и известна начальная последовательность байтов(для PNG/JPG), то можно вычислить и ключ и все такое.

0

11

Ну попробуй вычисли. Я щёлкни две фотки - одна истинная, вторая-ключ и пришлю тебе зашифрованный файл, а ты мне вышли результат который у меня истинный чтобы он совпал.

Отредактировано PSY (Вчера 18:25:35)

0

12

PSY
Ну не будете же вы с собой картинку таскать, теряется весь смысл пароля.

0

13

А если у меня много изображений то я могу просто знать какое из них - ключ. Или Музыка и видео. Кто мешает это использовать во качестве ключа.

0

14

PSY написал(а):

Ну попробуй вычисли. Я щёлкни две фотки - одна истинная, вторая-ключ и пришлю тебе зашифрованный файл, а ты мне вышли результат который у меня истинный чтобы он совпал.

Больно ты нужен что-то доказывать.

0

15

egons
Его вариант реальный, так как текстовая книга будет максимум 2 Мб, а тут на неё "картинку наложи" размером 4 Мб. По смыслу получится как шифровка, с разницей что каждый символ будет свой собственный, даже "а" в позиции 5 и "а" в позиции 15 будет ни одним и тем же символом, тут даже повторений не будет. Одно случайное число "сольётся" с другим случайным числом. По сути каждая буква-позиция имеет свой код. Нет даже алгоритма расшифровки такого.

Только алгоритм, который мы обсуждаем имеет короткий пароль, а метод с картинкой это необходимость иметь картинку.

Отредактировано AZJIO (Вчера 23:35:12)

0

16

AZJIO написал(а):

Его вариант реальный, так как текстовая книга будет максимум 2 Мб, а тут на неё "картинку наложи" размером 4 Мб.

Объясните мне, скудоумному, на кой ляд понадобились такие громадные картинки с громадными ключами шифрования?

0

17

Ну дык можно вообще использовать не только изображение во качестве ключа шифровки/расшифровки, а можно даже выбрать что угодно, даже какой-нибудь фильм или любой файл. Смысл исключающего ИЛИ в самом надёжном варианте - это размер ключа равен размеру входных данных или размер ключа более размера входных данных. Тогда результат шифрования - будет очень надёжным.

Отредактировано PSY (Сегодня 12:19:20)

0

18

Пётр
Сделал чтение по 10 Мб.

Обновление
Добавлена командная строка, для добавления программы в контекстное меню файлового менеджера.
Добавлено шифрование блоками по 10 Мб, не загружая весь файл в память.
Изменён формат ключа - хеш-сумма, вместо генерации байтов.
Исходник для Linux пока от предыдущей версии

0

19

AZJIO написал(а):

Исключающее или это уровень детсада

Шифрование - интересная тема, но и опасная тоже. Поиграешь с ним, а потом получается программа шифрования, после которой и сам уже не знаешь, как расшифровать текст, или бинарный файл, не зная входных параметров для шифрования.

И главное, даже зная, как я его зашифровал с несложным алгоритмом, потом сложно придумать алгоритм расшифровки, который бы даже на суперкомпьютере расшифровал бы полученный результат, потому что и для брутфорса нужно же с чем-нибудь сравнивать - получилась ли расшифровка в текущем варианте.

Так вот, играя с шифрованием можно получить результат, который потом какой-нибудь гад сможет использовать для злых дел. А ты только и сможешь потом рассказать свой алгоритм шифрования, а как расшифровать такую переписку, или такие файлы, и сам не придумаешь.

Тем более, что без проблем ведь в такой программе шифрования поставить еще один параметр: количество циклов шифрования. И все. На что тут потом натравливать суперкомпьютер для расшифровки, с чем ему сравнивать полученные переборы вариантов - всё равно получается сплошная бинарная каша и довольно равномерная. А если знаешь входные параметры для шифрования - то секунда работы, и текст/файл расшифрован.

Интересная тема, но похожая на изготовление чего-то опасного. Как у тех физиков в 30-е годах, которым было просто интересно, получится ли у них самоподдерживающаяся реакция расщепления атомов. Получилась. То-то обрадовались этому потом жители Хиросимы.

Отредактировано Nemo3001 (Сегодня 15:27:55)

0

20

Не увидел в коде функцию FinishCipher(), а должна быть.
Все же лучше переводить строку в бинарный вид о чем я писал выше. Это увеличит стойкость шифрования.
Сейчас в ключе и векторе могут быть только цифры от 0 до 9 и буквы от a до f.

Код:
UseMD5Fingerprint()

MD5.s = StringFingerprint("1234", #PB_Cipher_MD5, 0, #PB_Unicode)
Debug MD5

*MD5 = Ascii(MD5)
ShowMemoryViewer(*MD5, MemorySize(*MD5))

В бинарном виде будет весь диапазон значений байта - 0 - 255.

Код:
UseMD5Fingerprint()

Procedure HexToBin(s.s)
  Protected *Point=0, Pos=0, i, Count
   
  Count = Len(s)
  
  If Count > 0
    If Count % 2 <> 0 : Debug "Не кратно 2!!!! Возможна запись за пределы выделенной памяти!!!!" : EndIf
    *Point = AllocateMemory(Count / 2)
    If *Point
      For i=1 To Count Step 2
        PokeA(*Point+Pos, Val("$"+Mid(s, i, 2)))
        Pos+1
      Next
    EndIf
  EndIf
  
  ProcedureReturn *Point
EndProcedure

MD5.s = StringFingerprint("1234", #PB_Cipher_MD5, 0, #PB_Unicode)
Debug MD5

*MD5 = HexToBin(MD5)
ShowMemoryViewer(*MD5, MemorySize(*MD5))

0


Вы здесь » PureBasic - форум » PureBasic для Windows » Кодировать / декодировать файл