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-битный ввод, поэтому вы можете с помощью другой функции создать более длинный массив масок для повышения уровня безопасности.

Другие вопросы по тегам