Szyfrowanie/deszyfrowanie za pomocą XOR

0

Witam, Próbuję zrealizować proste szyfrowanie/deszyfrowanie XORem (to moje pierwsze zetknięcie z szyfrowaniem a nie ograniam tych szyfrowań AES itp. więc chciałem zrobić chociaż takie nieskomplikowane jak XOR),
Potrzebuję zrobić to tak by wynik szyfrowania był w zakresie ASCII ( od '!' do '~') tzn potrzebuje się pozbyć "dziwnych" znaków które mogę powodować problemy przy przesyłaniu stringów RS232 (np.znak końca linii).

Na razie mam to zrobione w taki sposób:

var
  i, j, kluczdl, x,y: Integer;
  str, str2, klucz: String;
  b,c : char;
  a: char;
  licz: Integer;
begin
  str := Edit3.Text;
  klucz := Edit2.Text;
  kluczdl := Length(klucz);
  j := 1;
  str2 := '';
  for i := 1 to Length(str) do begin
    b := str[i];
    x := ord(b);
    y := ord(klucz[j]);
    y := y - 23;
    c := Chr( x xor y );
    str2 := str2 + c;
    inc(j);
    if j > kluczdl then j := 1;
  end;

Edit4.Text := str2;

end;

To co mi przychodzi do głowy to zmiana: c := Chr(33 + (x xor y) ); to nam powinno "zabezpieczyć" zakres ASCII od dołu a z góry ? I jak to potem odszyfrować prawidłowo ?

0

Podstawowe pytanie – jaki jest dopuszczalny zakres znaków wejściowych?

Poczytaj też o Base64.

0

Zakres danych wejściowych jest taki sam jak chce uzyskać wyjściowych czyli ASCII ( od '!' do '~')

0

Samym xor-em nic nie zdziałasz, bo jeśli ciąg wejściowy oraz ciąg klucza zawierają wyłącznie znaki z przedziału <33;126>, to xor-owanie zwróci kody z przedziału <0;127>, czyli pełne ASCII. Prosty tester:

var
  Min: UInt8 = 255;
  Max: UInt8 = 0;
  Code: UInt8;
var
  X, Y: Char;
begin
  for X := '!' to '~' do
    for Y := '!' to '~' do
    begin
      Code := UInt8(X) xor UInt8(Y);

      if Code < Min then Min := Code;
      if Code > Max then Max := Code;
    end;

  WriteLn('Min: ', Min);
  WriteLn('Max: ', Max);
end.

Na wyjściu dostajemy:

Min: 0
Max: 127

Albo skorzystaj z sensownego algorytmu szyfrującego, albo klucz generuj w taki sposób, aby xor-owanie nie generowało znaków kontrolnych. Choć to może być awykonalne.

0

aha ... kiepskie pociesze, szukałem czegoś innego np. AES, ale nie mogłem znaleźć sensownej implementacji z łopatologicznym wytłumaczeniem jak tego użyć.

Ogólnie to potrzebuje tego szyfrowania do zabezpieczenia transmisji po RS232 między prockiem avr a PC. Do avr znalazłem biblioteki tutaj: http://dominik.cc/projekty/avr-aes/

Ale jak to ogarnąć po stronie Delphi to nie wiem :(

0

Przecież jeżeli nie musisz sam tego pisać to do AESów itp. masz pełno gotowych bibliotek :)

0
nowumfor napisał(a):

aha ... kiepskie pociesze […]

Dlaczego? Rozwiązanie najprawdopodobniej istnieje. Wystarczy tylko wykazać, że dla dowolnego ciągu wejściowego spełniającego wymagania (co do zawartości), istnieje skończona liczba ciągów kluczy, dla których ”szyfrowanie” xor-em nie zwróci ani jednego znaku kontrolnego.

Jak chcesz i masz czas to napisz sobie taki tester i wykaż, że da się to wykonać.

Ogólnie to potrzebuje tego szyfrowania do zabezpieczenia transmisji po RS232 między prockiem avr a PC. Do avr znalazłem biblioteki tutaj: http://dominik.cc/projekty/avr-aes/

W przypadku algorytmów szyfrowania przyjęło się, aby nie stosować własnych implementacji, bo nie jest to bezpieczne. Popularne i powszechnie wykorzystywane algorytmy zostały wielokrotnie sprawdzone pod kątem bezpieczeństwa przez mądre głowy, więc ich użycie jest jak najbardziej sensowne i zalecane.

0

ok. Zmieniłem w kodzie wyżej

Code := 33 + ((UInt8(X) xor UInt8(Y))  mod 94);

Teraz są znaki z zakresu: <33;126>

Problem teraz jak "wymyślić" odkodowanie tego działania ?

To proszę o wskazanie gdzie tego szukać żeby było sensownie wyjaśnione jak tego użyć bo powiedzenie że tęgie głowy wymyśliły nie jedno i wszystko jest u wujka google, to można byle co znaleźć, ale dla ludzi tak zielonych w temacie implementacja tego nie jest łatwa.

0

W ten sposób nie dasz rady – operacja modulo nie jest odwracalna, więc przy odkodowywaniu nie da się określić, czy dodać do bazowego kodu 94, czy nie.

0

Koniec końców po całym dniu "zabawy" udało mi się znaleźć i zaimplementować kodowanie Base64 nie bogate to ale zawsze i co najważniejsze działa

0

Jedna rzecz wyszła w czasie działania.. mianowicie wygląda mi na to że długość dekodowanego stringa jest ograniczona. Mógłby ktoś zobaczyć co tutaj należy zmienić żeby dekodować dłuższe stringi ?

int Base64decode(char *bufplain, char *bufcoded)
{
    int nbytesdecoded;
    register const unsigned char *bufin;
    register unsigned char *bufout;
    register int nprbytes;

    bufin = (const unsigned char *) bufcoded;
    while (pr2six[*(bufin++)] <= 63);
    nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
    nbytesdecoded = ((nprbytes + 3) / 4) * 3;

    bufout = (unsigned char *) bufplain;
    bufin = (const unsigned char *) bufcoded;

    while (nprbytes > 4) {
    *(bufout++) =
        (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
    *(bufout++) =
        (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
    *(bufout++) =
        (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
    bufin += 4;
    nprbytes -= 4;
    }

    /* Note: (nprbytes == 1) would be an error, so just ingore that case */
    if (nprbytes > 1) {
    *(bufout++) =
        (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
    }
    if (nprbytes > 2) {
    *(bufout++) =
        (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
    }
    if (nprbytes > 3) {
    *(bufout++) =
        (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
    }

    *(bufout++) = '\0';
    nbytesdecoded -= (4 - nprbytes) & 3;
    return nbytesdecoded;
}
0

sory niemogę skasować ... a olśniło mnie że zrobiłem błąd w innym miejscu programu ;)

0

Możesz stowrzyc plik binarny - bez nagłówka losowy klucz i szyfrować wg niego wszystko, zapisywać również binarnie. Następnie odwrócić proces... jeśli zgubisz taki klucz to nikt tego nie odszyfruje już.

1 użytkowników online, w tym zalogowanych: 0, gości: 1