Delphi: XOR, HEX, шифрование
Есть ли способ шифрования с помощью XOR и представления в HEX (и наоборот). (Я полагаю, нет, не мог найти это).
Есть ли альтернатива? Я не хочу использовать Base64.
Поэтому мне нужно зашифровать и представить результат в удобочитаемой форме.
4 ответа
Вот функция, применяющая XOR к строке и возвращающая результат в шестнадцатеричном виде:
function XorToHex(const Source: string; Code: char): string;
const
HexChars: array[0..15] of char = '0123456789ABCDEF';
var i: Integer;
c: Integer;
begin
SetLength(Result,Length(Source)*(sizeof(char)*2));
for i := 1 to Length(Source) do begin
c := Ord(Source[i]) xor Ord(Code);
{$IFDEF UNICODE}
result[i*4-3] := HexChars[(c and 7) shr 4];
result[i*4-2] := HexChars[(c and 7) and 15];
c := c shr 8;
result[i*4-1] := HexChars[c shr 4];
result[i*4] := HexChars[c and 15];
{$ELSE}
result[i*2-1] := HexChars[c shr 4];
result[i*2] := HexChars[c and 15];
{$ENDIF}
end;
end;
Такой базовый XOR совсем не силен. Очень легко угадать код ключа, который является только одним символом.
Но эта функция будет работать как со строками Unicode, так и со строками Unicode.
Все вы указываете, насколько слабым является xor-шифрование, но вы все подумали об использовании только одного значения для xor. Вместо этого вы можете легко переписать строку с помощью другой строки - ключа. Чем длиннее ключ, тем сильнее реальное шифрование, и с достаточно длинным ключом его действительно трудно взломать.
Вы можете даже xor-зашифровать поток памяти, так же как и строку:
Procedure XorStream(const StreamToXor: TMemoryStream; const XorKey: string);
var
i,k : int64;
PC : PChar;
begin
if(StreamToXor=nil)then exit;
if(StreamToXor.Size<1)then exit;
if(XorKey='')then exit;
PC := StreamToXor.Memory;
k := 0;
for i:=0 to StreamToXor.Size-1 do
begin
inc(k); if(k>Length(XorKey))then k := 1;
PC[i] := char(byte(PC[i]) xor byte(XorKey[k]));
end;
end;
Шифрование XOR называется Stream Cypher, вы можете Google для разных версий.
Преобразование массива байтов в шестнадцатеричный код - это всего лишь вопрос выражения каждого отдельного байта в базе 16 с нулевым заполнением для байтов от 0x00 до 0x0F.
В чем конкретно ваша проблема с любым из них?
Использование бинарной функции xor для шифрования - плохое мужское шифрование. Это просто и быстро, но легко найти ключ маски кодирования.
Вот вам простой тестовый пример:
program Projecth1;
{$APPTYPE CONSOLE}
uses SysUtils;
var
Mask :cardinal = $12345678;
n :cardinal;
begin
n := $11223344;
writeln('input: $' + IntToHex(n, 8));
n := n xor Mask;
writeln('encode: $' + IntToHex(n, 8));
n := n xor Mask;
writeln('decode: $' + IntToHex(n, 8));
readln;
end.
В этом тестовом примере используются только 32-битная маска и 32-битный ввод, поэтому вы можете с помощью другой функции создать более длинный массив масок для повышения уровня безопасности.