courses:unix:lab_crypt

  • Pakiety w systemie wymagane do dzisiejszych zajęć: gnupg gnupg-doc gpa mcrypt openssh-client openssh-server
  • Potrzebny będzie dostęp shellowy do dwóch maszyn - jedna może być lokalna (np. laptop, maszyna wirtualna; albo może być zdalna), druga musi mieć dostęp przez SSH (np. serwer SPK)

1. Podstawowe pojęcia

  • kryptografia
  • kryptologia
  • szyfr (ang. cipher)
  • tekst jawny,
  • kryptogram,
  • klucz (ang. key)
  • hash, skrót (ang. hash, digest)
  • szyfrowanie bez klucza: ROT13 (ROT3 - Szyfr C.I.Cezara)
  • szyfrowanie z kluczem symetrycznym, np.: Crypt, DES, 3DES, Idea, Blowfish
  • szyfrowanie z kluczem asymetrycznym (publicznym), np: RSA, DSA, ElGamal
  • algorytmy generowania skrótu, np: MD5, SHA
  • podpis elektroniczny

2. Szyfrowanie z kluczem symetrycznym

Nadawca i odbiorca mają ten sam klucz.

Nadawca:

  • przygotowuje tekst wiadomości,
  • szyfruje całość wiadomości kluczem,
  • wysyła szyfrogram do odbiorcy.

Odbiorca:

  • rozszyfrowuje szyfrogram przy pom. klucza
  • otrzymuje tekst wiadomości

Oprócz szyfrogramu musi być przekazany klucz!

3. Szyfrowanie z kluczem asymetrycznym

Nadawca i Odbiorca mają pary własnych kluczy (Pub/Prv). Wymieniają się publicznymi.

Nadawca:

  • przygotowuje tekst wiadomości,
  • szyfruje wiadomość kluczem publicznym odbiorcy,
  • wysyła szyfrogram do odbiorcy.

Odbiorca:

  • rozszyfrowuje szyfrogram przy pomocy swojego klucza prywatnego,
  • otrzymuje tekst wiadomości.

4. Narzędzie mcrypt

Narzędzie mcrypt nie jest dostępne na serwerze spk, ale warto je znać, bo jest podstawowym narzędziem do symetrycznego szyfrowania plików. Można zainstalować je samodzielnie na własnej maszynie (pakiet mcrypt)

# lista dostępnych algorytmów szyfrowania (cbc, cfb i in. to dostępne tryby szyfrów blokowych)
$ mcrypt --list
cast-128 (16): cbc cfb ctr ecb ncfb nofb ofb 
gost (32): cbc cfb ctr ecb ncfb nofb ofb 
rijndael-128 (32): cbc cfb ctr ecb ncfb nofb ofb 
twofish (32): cbc cfb ctr ecb ncfb nofb ofb 
arcfour (256): stream 
cast-256 (32): cbc cfb ctr ecb ncfb nofb ofb 
loki97 (32): cbc cfb ctr ecb ncfb nofb ofb 
rijndael-192 (32): cbc cfb ctr ecb ncfb nofb ofb 
saferplus (32): cbc cfb ctr ecb ncfb nofb ofb 
wake (32): stream 
blowfish-compat (56): cbc cfb ctr ecb ncfb nofb ofb 
des (8): cbc cfb ctr ecb ncfb nofb ofb 
rijndael-256 (32): cbc cfb ctr ecb ncfb nofb ofb 
serpent (32): cbc cfb ctr ecb ncfb nofb ofb 
xtea (16): cbc cfb ctr ecb ncfb nofb ofb 
blowfish (56): cbc cfb ctr ecb ncfb nofb ofb 
enigma (13): stream 
rc2 (128): cbc cfb ctr ecb ncfb nofb ofb 
tripledes (24): cbc cfb ctr ecb ncfb nofb ofb
# Szyfrowanie pliku "plik" (powstaje plik.nc; nc = eNCrypted)
$ mcrypt -a des plik 
Wprowadź hasło (maksymalnie 512 znaków)
Proszę użyć kombinacji cyfr i małych i wielkich liter.
Wprowadź hasło: 
Wprowadź hasło: 

File plik was encrypted.
# Deszyfrowanie pliku
$ mdecrypt plik.nc
Wprowadź hasło: 
File plik.nc was decrypted.

5. Wykorzystanie funkcji skrótu

# Wyliczanie funkcji skrótu MD5
$ md5sum plik
0eb376701ee34505840e4b3c47baf894  plik
$ md5sum /bin/bash
557c0271e30cf474e0f46f93721fd1ba  /bin/bash

# Funkcja skrótu ma taką samą długość, mimo że pliki są różnej długości
$ du -h /bin/bash moj_plik
1,1M	/bin/bash
4,0K	plik

6. Podpis elektroniczny

Nadawca i Odbiorca mają pary własnych kluczy (Pub/Prv). Wymieniają się publicznymi.

Nadawca:

  • przygotowuje tekst wiadomości,
  • wylicza skrót wiadomości (np. MD5),
  • szyfruje skrót przy pomocy swojego klucza prywatnego,
  • [jeżeli poza podpisaniem chcemy również zaszyfrować] szyfrujemy całość: tekst i zaszyfrowany skrót, kluczem publicznym odbiorcy,
  • wysyła wiadomość i zaszyfrowany skrót do odbiorcy.

Odbiorca:

  • [jeżeli poza podpisaniem, wiadomość jest również zaszyfrowana] rozszyfrowuje szyfrogram przy pomocy swojego klucza prywatnego,
  • otrzymuje tekst wiadomości oraz jej zaszyfrowany skrót,
  • rozszyfrowuje zaszyfrowany skrót przy pomocy klucza publicznego nadawcy,
  • wylicza samodzielnie skrót wiadomości,
  • porównuje wyliczony skrót z rozszyfrowanym,
  • jeżeli są zgodne, potwierdzone zostają tożsamość nadawcy i spójność przesłanych informacji.

7. Gnu Privacy Guard

Najważniejsze etapy używania programu (szczegóły we fragmentach kodu poniżej):

  • wygenerowanie kluczy
    $ gpg --full-generate-key
    gpg (GnuPG) 2.2.4; Copyright (C) 2017 Free Software Foundation, Inc.
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    
    gpg: directory '/home/kutt/.gnupg' created
    gpg: keybox '/home/kutt/.gnupg/pubring.kbx' created
    Proszę wybrać rodzaj klucza:
       (1) RSA i RSA (domyślne)
       (2) DSA i Elgamala
       (3) DSA (tylko do podpisywania)
       (4) RSA (tylko do podpisywania)
    Twój wybór? 1
    Klucze RSA będą miały od 1024 do 4096 bitów długości.
    Jakiej długości klucz wygenerować? (3072) 
    Żądana długość klucza to 3072 bitów.
    Okres ważności klucza.
             0 = klucz nie ma określonego terminu ważności
          <n>  = termin ważności klucza upływa za n dni
          <n>w = termin ważności klucza upływa za n tygodni
          <n>m = termin ważności klucza upływa za n miesięcy
          <n>y = termin ważności klucza upływa za n lat
    Okres ważności klucza? (0) 
    Klucz nie wygaśnie w ogóle
    Czy wszystko się zgadza (t/N)? t
    
    GnuPG musi utworzyć identyfikator użytkownika do identyfikacji klucza.
    
    Imię i nazwisko: Krzysztof Kutt
    Adres poczty elektronicznej: krzysztof.kutt@uj.edu.pl
    Komentarz: UJ
    Twój identyfikator użytkownika będzie wyglądał tak:
        "Krzysztof Kutt (UJ) <krzysztof.kutt@uj.edu.pl>"
    
    Zmienić (I)mię/nazwisko, (K)omentarz, adres (E)mail, przejść (D)alej,
    czy (W)yjść z programu? D
    Musimy wygenerować dużo losowych bajtów. Dobrym pomysłem aby pomóc komputerowi
    podczas generowania liczb pierwszych jest wykonywanie w tym czasie innych
    działań (pisanie na klawiaturze, poruszanie myszką, odwołanie się do dysków);
    dzięki temu generator liczb losowych ma możliwość zebrania odpowiedniej ilości
    entropii.
    gpg: /home/kutt/.gnupg/trustdb.gpg: baza zaufania utworzona
    gpg: klucz EA188E410EB2C17B został oznaczony jako obdarzony absolutnym zaufaniem.
    gpg: directory '/home/kutt/.gnupg/openpgp-revocs.d' created
    gpg: revocation certificate stored as '/home/kutt/.gnupg/openpgp-revocs.d/2237165D8C8DC756C1BF9D91EA188E410EB2C17B.rev'
    klucz publiczny i prywatny (tajny) zostały utworzone i podpisane.
    
    pub   rsa3072 2021-04-23 [SC]
          2237165D8C8DC756C1BF9D91EA188E410EB2C17B
    uid                      Krzysztof Kutt (UJ) <krzysztof.kutt@uj.edu.pl>
    sub   rsa3072 2021-04-23 [E]
  • zarządzanie kluczami: wyświetlanie kluczy, export swojego klucza, import czyjegoś, edycja
    # wyświetlanie wszystkich kluczy
    $ gpg --list-keys
    /home/kutt/.gnupg/pubring.kbx
    -----------------------------
    pub   rsa3072 2021-04-23 [SC]
          2237165D8C8DC756C1BF9D91EA188E410EB2C17B
    uid           [    absolutne   ] Krzysztof Kutt (UJ) <krzysztof.kutt@uj.edu.pl>
    sub   rsa3072 2021-04-23 [E]
    
    # ---------------------------------------------------
    
    # export własnego klucza
    $ gpg -a --export kutt > moj_klucz_publiczny.asc
    $ file moj_klucz_publiczny.asc 
    moj_klucz_publiczny.asc: PGP public key block Public-Key (old)
    
    # ---------------------------------------------------
    
    # import cudzego klucza
    $ gpg --import gjn_public.asc 
    gpg: klucz 5AB733FD8FB5187A: klucz publiczny ,,Grzegorz J. Nalepa (UJ) <gjn@gjn.re>'' wczytano do zbioru
    gpg: Ogółem przetworzonych kluczy: 1
    gpg:               dołączono do zbioru: 1
    
    $ gpg --list-keys
    /home/kutt/.gnupg/pubring.kbx
    -----------------------------
    pub   rsa3072 2021-04-23 [SC]
          2237165D8C8DC756C1BF9D91EA188E410EB2C17B
    uid           [    absolutne   ] Krzysztof Kutt (UJ) <krzysztof.kutt@uj.edu.pl>
    sub   rsa3072 2021-04-23 [E]
    
    pub   rsa3072 2021-04-23 [SC]
          416C5029A116A059D48726895AB733FD8FB5187A
    uid           [    nieznane   ] Grzegorz J. Nalepa (UJ) <gjn@gjn.re>
    sub   rsa3072 2021-04-23 [E]
    
    # ---------------------------------------------------
    
    # edycja klucza (zostanie podpisany, aby wskazać, że jest zaufany)
    $ gpg --edit-key gjn
    gpg (GnuPG) 2.2.4; Copyright (C) 2017 Free Software Foundation, Inc.
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    
    pub  rsa3072/5AB733FD8FB5187A
         utworzono: 2021-04-23  wygasa: nigdy       użycie: SC  
         zaufanie: nieznany      poprawność: nieznany
    sub  rsa3072/8AC4381E38BF3114
         utworzono: 2021-04-23  wygasa: nigdy       użycie: E   
    [    nieznane   ] (1). Grzegorz J. Nalepa (UJ) <gjn@gjn.re>
    
    gpg> sign
    
    pub  rsa3072/5AB733FD8FB5187A
         utworzono: 2021-04-23  wygasa: nigdy       użycie: SC  
         zaufanie: nieznany      poprawność: nieznany
     Odcisk klucza głównego: 416C 5029 A116 A059 D487  2689 5AB7 33FD 8FB5 187A
    
         Grzegorz J. Nalepa (UJ) <gjn@gjn.re>
    
    Czy jesteś naprawdę pewien, że chcesz podpisać ten klucz
    swoim kluczem ,,Krzysztof Kutt (UJ) <krzysztof.kutt@uj.edu.pl>'' (EA188E410EB2C17B)
    
    Czy na pewno podpisać? (t/N) t
    
    gpg> quit
    Zapisać zmiany? (t/N) t
    
    
    # sprawdź jak zmienił się poziom zaufania (w nawiasach kwadratowych)
    $ gpg --list-keys
    /home/kutt/.gnupg/pubring.kbx
    -----------------------------
    pub   rsa3072 2021-04-23 [SC]
          2237165D8C8DC756C1BF9D91EA188E410EB2C17B
    uid           [    absolutne   ] Krzysztof Kutt (UJ) <krzysztof.kutt@uj.edu.pl>
    sub   rsa3072 2021-04-23 [E]
    
    pub   rsa3072 2021-04-23 [SC]
          416C5029A116A059D48726895AB733FD8FB5187A
    uid           [      pełne    ] Grzegorz J. Nalepa (UJ) <gjn@gjn.re>
    sub   rsa3072 2021-04-23 [E]
  • szyfrowanie pliku
    # --armor = wynik będzie plikiem tekstowym, a nie binarnym
    # -r gjn = wybieramy klucz publiczny odbiorcy, w którym częścią identyfikatora jest "gjn"
    # -o plik.asc = powstanie plik o nazwie plik.asc
    $ gpg --encrypt --armor -r gjn -o plik.asc plik
    
    $ head -5 plik.asc
    -----BEGIN PGP MESSAGE-----
    
    hQGMA4rEOB44vzEUAQwArV/i52Y59t9eubCDFscM+fPi61qOABS42BuWArFred0z
    X8qlarO5WtdfBwJ+0UYi6K3QLhVlouft4kv2+cfAufPs5vISqtvPdhsZUt21VWrd
    ALe6UHnGpWrcaBjF5pNtY+lN0h6tt9l7jFDWkYcWzGJ/BFbI2h57hHdZttoBWhG7
    
    $ file plik.asc
    plik.asc: PGP message Public-Key Encrypted Session Key (old)
  • deszyfrowanie pliku
    $ gpg --decrypt -o otrzymany-plik otrzymany-plik.asc
    gpg: zaszyfrowano 3072-bitowym kluczem RSA o identyfikatorze 28EE2447375F2314, stworzonym 2021-04-23
          ,,Krzysztof Kutt (UJ) <krzysztof.kutt@uj.edu.pl>''
  • podpisywanie pliku
    # podpisywanie wiadomości za pomocą --sign
    $ gpg --sign --armor -o podpisany-plik.sign plik
    
    # wiadomość NIE jest zaszyfrowana, ale nie da się jej odczytać bezpośrednio z pliku
    $ head -5 podpisany-plik.sign 
    -----BEGIN PGP MESSAGE-----
    
    owEB7gER/pANAwAKAeoYjkEOssF7AawnYgRwbGlrYILv+0JsYWggQmxhaCBCbGFo
    ClJheiBEd2EgVHJ6eQoKiQGzBAABCgAdFiEEIjcWXYyNx1bBv52R6hiOQQ6ywXsF
    AmCC7/sACgkQ6hiOQQ6ywXvtwQv/awZCpTt9sUEAjGbB0kt/ODvUZKzlrJj3SrGU
    
    # ---------------------------------------------------
    
    # podpisywanie wiadomości za pomocą --clearsig
    $ gpg --clearsig -o podpisany-plik.sign plik
    
    # tutaj wiadomość jest podzielona na dwa bloki - wiadomość i podpis
    $ cat podpisany-plik.sign
    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA512
    [tutaj znajduje się wiadomość]
    -----BEGIN PGP SIGNATURE-----
    [tutaj znajduje się podpis = zaszyfrowany hash]
    -----END PGP SIGNATURE-----
    
    # ---------------------------------------------------
    
    # użyteczność pliku i podpisu połączonego w jeden plik jest mała
    # dlatego najlepiej skorzystać z opcji --detach-sign, dzięki której powstanie SAM podpis
    # który trzeba przekazać RAZEM z właściwym plikiem
    $ gpg --sign --armor -o podpis.sign --detach-sign plik
    
    # tutaj jest tylko podpis
    $ cat podpisany-plik.sign
    -----BEGIN PGP SIGNATURE-----
    [tutaj znajduje się podpis = zaszyfrowany hash]
    -----END PGP SIGNATURE-----
  • weryfikacja podpisu
    # Weryfikacja wiadomości zawierającej podpis
    $ gpg --verify podpisany-plik.sign
    gpg: Podpisano w pią, 23 kwi 2021, 18:06:32 CEST
    gpg:                przy użyciu klucza RSA 2237165D8C8DC756C1BF9D91EA188E410EB2C17B
    gpg: Poprawny podpis złożony przez ,,Krzysztof Kutt (UJ) <krzysztof.kutt@uj.edu.pl>'' [absolutne]
    
    # ---------------------------------------------------
    
    # Weryfikacja wiadomości (gdy podpis i wiadomość są OSOBNYMI plikami)
    $ gpg --verify podpis.sign plik
    gpg: Podpisano w pią, 23 kwi 2021, 18:23:57 CEST
    gpg:                przy użyciu klucza RSA 2237165D8C8DC756C1BF9D91EA188E410EB2C17B
    gpg: Poprawny podpis złożony przez ,,Krzysztof Kutt (UJ) <krzysztof.kutt@uj.edu.pl>'' [absolutne]
  • szyfrowanie i podpisywanie równocześnie
    # Zauważ, że przed "-sear" jest jedna pauza = to są 4 krótkie opcje
    $ gpg -sear gjn -o plik.asc plik

8. Uwierzytelnianie SSH

Przebieg:

  • serwer SSH ma parę kluczy (publiczny i prywatny),
  • klient rozpoczyna transmisję szyfrowaną przy pomocy klucza publicznego serwera (algorytm asymetryczny, np. DSA/RSA),
  • podejmowana jest próba uwierzytelnienia użytkownika, (jedną z wybranych metod: klucz, hasło, OTP, itp.), najczęściej:
    • jeżeli to możliwe, przeprowadzane jest uwierzytelnienie przy pomocy klucza publicznego użytkownika,
    • jeżeli nie jest możliwe uwierzytelnianie przy pomocy kluczy realizowane jest uwierzytelnianie poprzez hasło,
  • w przypadku pomyślnego uwierzytelnienia reszta sesji jest szyfrowana przy pomocy algorytmu symetrycznego (3DES, Idea, Blowfish) z kluczem losowanym na nowo dla każdej sesji,
  • transmisja może być opcjonalnie kompresowana,
  • zamiast uruchomienia powłoki interaktywnej można uruchomić dowolny program.

Uwierzytelnianie przez klucz publiczny SSH:

  • Wymaga wygenerowania pary kluczy na maszynie z której się logujemy.
  • Przeniesienia klucza publicznego na maszynę na którą się logujemy.
  • Klucze są zabezpieczane passfrazami.
  • Zawierają również informacje o koncie na którym zostały stworzone.
  • Pozwala to na uwierzytelenienie: użytkownika i maszyny (miejsca) z którego się loguje.
  • Uwierzytelnienie jest dwustopniowe: hasło (passfraza) i token (klucz).

Konfiguracja:

  • wygenerowanie kluczy na maszynie z której się logujemy (np. nasz prywatny komputer):
    moj-laptop$ ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/kkutt/.ssh/id_rsa): 
    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again: 
    Your identification has been saved in /home/kkutt/.ssh/id_rsa.
    Your public key has been saved in /home/kkutt/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:VIEzJAtY57zQSmGFEkHOnqQWnhI/1F5EqeyuqvogVz0 kkutt@moj-laptop
  • skopiowanie klucza publicznego na maszynę na którą się logujemy (np. serwer SPK):
    moj-laptop$ scp .ssh/id_rsa.pub kutt@149.156.43.64:.ssh/id_rsa.pub-moj-laptop
    kutt@149.156.43.64's password: 
    id_rsa.pub                                    100%  395    82.3KB/s   00:00 
  • dopisanie klucza publicznego do listy kluczy autoryzowanych:
    moj-laptop$ ssh kutt@149.156.43.64 'cat .ssh/id_rsa.pub-moj-laptop >> .ssh/authorized_keys'
    kutt@149.156.43.64's password: 
  • teraz można już logować się przy pomocy klucza (logujemy się w taki sposób jak zawsze, ssh wykryje, że istnieje pasująca para kluczy):
    moj-laptop$ ssh kutt@149.156.43.64
    Enter passphrase for key '/home/kkutt/.ssh/id_rsa': 
    
    kutt@spk-ssh:~$ 
  • przekazywanie autoryzacji przez SSH Agent (w danej sesji nie trzeba będzie ponownie podawać passphrase):
    moj-laptop$ ssh-add .ssh/id_rsa
    Enter passphrase for /home/kkutt/.ssh/id_rsa: 
    Identity added: /home/kkutt/.ssh/id_rsa (kkutt@moj-laptop)
    
    moj-laptop$ ssh [-A] kutt@149.156.43.64
    
    kutt@spk-ssh:~$

I. GnuPG

  1. wygenerować swój klucz, gpg -‐gen-key albo gpg –full-generate-key (wszystkie wartości domyślne są w porządku, możemy je zostawić)
  2. NIE należy podpisywać kluczy (-‐sign)
  3. zaszyfrować i rozszyfrować wybrany plik dla siebie,
  4. wymienić się kluczami z drugą osobą, za/rozszyfrować dla siebie pliki, (należy wyeksportować swój klucz publiczny, przekazać drugiej osobie, i zaimportować jej/jego wyeksportowany klucz publiczny):
    • pracując na serwerze SPK można przejść do katalogu /tmp: cd /tmp, do którego wszyscy mamy dostęp = wszystkie pliki (klucze, pliki do zaszyfrowania) można umieścić w tym katalogu i druga osoba będzie miała do nich dostęp (sprawdzić UPRAWNIENIA DOSTĘPU)
    • wyświetlić listę kluczy: gpg -‐list-keys
    • UWAGA: identyfikator klucza, to dowolny fragment linii z napisem (a nie login!)
    • eksport klucza: -‐export
    • import klucza: -‐import
  5. podpisać elektronicznie plik,
  6. podpisać elektronicznie plik i zaszyfrować dla drugiej osoby.

II. SSH

  1. Prześledzić nawiązywanie połączenia z serwerem SSH (logować się dodając opcję -v (ssh -v [konto@]maszyna))
  2. Wygenerować na maszynie A parę kluczy, przenieść publiczny na maszynę B, zalogować się z A na B przy pomocy klucza.
  3. Co należy zrobić, aby w danej sesji (na A) przy kolejnym logowaniu na B nie musieć podawać passfrazy do klucza?

III. Hashe

  1. Wyliczyć przy pomocy md5sum skrót wybranego pliku.
  2. jak wyżej, tylko dla pliku o innej długości, porównać długość hasha.
  3. Zmodyfikować wcześniej używany plik, np. echo a » plik, wyliczyć hash i porównać z wcześniejszym.
  4. Wyliczyć hashe dla podanej grupy plików (przy pomocy jednego wywołania md5sum) i zapisać je do pliku MD5SUMS.

IV. Mcrypt

Narzędzie mcrypt nie jest dostępne na serwerze spk, ale warto je znać, bo jest podstawowym narzędziem do symetrycznego szyfrowania plików. Można zainstalować je samodzielnie na własnej maszynie (pakiet mcrypt)

Przy pomocy wybranego algorytmu symetrycznego za/rozszyfrować plik za pomocą mcrypt.

V. Narzędzia GPG

Pracę z GPG mogą wspomagać:

  • courses/unix/lab_crypt.txt
  • Last modified: 4 years ago
  • by 127.0.0.1