Certyfikaty oparte o SSL stanowią obecnie podstawę bezpieczeństwa wielu usług sieciowych zaczynając od HTTP, przez POPS, IMAPS, itd… Niestety zakupienie certyfikatu w organizacjach jak VeriSgin czy Thawte jest dość kosztowe, a jeżeli potrzebujemy kilka certyfikatów to często na lokalne potrzeby jest to po prostu nie opłacalne.

Postaram się przedstawić wersję “ekonomiczną” certyfikacji 😃

Generowanie Certificate Signing Request

Pierwszym etapem generowania certyfikatu jest przygotowanie Certificate Signing Request, czyli czegoś w rodzaju “prośby” o certyfikat. Nasza “prośba” po podpisaniu przez centrum autoryzacyjne stanie się certyfikatem.

Do wygenerowania Request’u potrzebny jest najpierw klucz prywatny, który generujemy np. tak:

openssl genrsa -aes256 -out priv.key 4096

Powyższe polecenie poprosi nas dwa razy o hasło, które trzeba zapamiętać (albo zapisać i zamknąć w sejfie) - zalecam wykorzystanie pseudolosowego ciągu znaków o długości minimum 10 znaków.

Po genrsa możemy użyć kilku opcji wybierając w ten sposób algorytm szyfrujący - do wyboru są: des, des3, aes128, aes192, aes256. Ja wybrałem 256-bitowego AES’a - najmocniejszy z tych algorytmów.

Ostatni parametr do długość klucza. Można użyć innej wartości np. 1024. Klucz wygeneruje się szybciej ale będzie prostszy do złamania. Z moich doświadczeń wynika, że niektóre aplikacje mogą mieć problem z obsługą długiego klucza (np. jak użyty w tym przykładzie), wtedy użycie mniejszej wartości może być konieczne (lepsze słabsze zabezpieczenie niż żadne).

Warto ograniczyć uprawnienia do wygenerowanego klucza prywatnego tak by tylko właściciel miał do niego dostęp:

chmod 400 priv.key

Przy okazji tworzenia klucza prywatnego warto wspomnieć, że jeżeli będziemy chcieli go użyć w tak przygotowanej postaci np. w Apache’m to przy każdym starcie Apache będzie nas prosić o podanie hasła odbezpieczającego klucz prywatny. Niby to bezpieczne ale z drugiej strony przez takie zabezpieczenie Apache nie podniesie się samodzielnie np. po awarii. Rozwiązaniem jest przygotowanie odszyfrowanej wersji klucza prywatnego, z której będzie korzystał Apache. Robi się to tak:

openssl rsa -in priv.key -out priv.unsecure.key
chmod 400 priv.unsecure.key

Klucz priv.unsecure.key podany w konfiguracji programu nie będzie wymagał hasła. Koniecznie należy uniemożliwić dostęp do tego pliku wszystkim z wyjątkiem root’a!

openssl req -new -key priv.key -out request.csr

Co dalej?

Ok. Mamy już request’a, warto w tym miejscu wspomnieć co możemy z nim zrobić:

  • Możemy taki plik przesłać do centrum autoryzacji (CA) celem podpisania i wygenerowania certyfiaktu. Klucze publiczne CA takich jak Thawte, VeriSign, itp są dołączane do przeglądarek internetowych, OS’ów, etc. dzięki temu strony internetowe (bądź inne usługi) zabezpieczone takimi certyfikatami weryfikują się bez żadnej dodatkowej akcji ze strony użytkownika. Warto wziąć pod uwagę to rozwiązanie, jeżeli np. chcemy zabezpieczyć sklep internetowy - my odpuścimy to rozwiązanie ze względu na koszty 😃
  • Drugą opcją jest możliwość samodzielnego podpisania certyfikatu tworząc tzw. SelfSigned Certificate. To zalecana opcja jeżeli mamy tylko jedną stronę/usługę. Użytkownik raz doda sobie nasz certyfikat jako zaufany i będzie mógł korzystać z szyfrowania do woli. Metoda ta robi się problematyczna gdy trzeba zarządzać większą liczbą certyfikatów.
  • Ostatnia opcja to utworzenie własnego CA (czyli specjalnego certyfikatu), którym będziemy podpisywać wygenerowane przez nas Requesty. Ma to tę zaletę, że wystarczy rozdystrybuować klucz publiczny CA i będzie to wystarczające do weryfikacji wszystkich naszych certyfikatów.

Tworzenie certyfikatów SelfSigned

Zaczniemy od prostszej wersji czyli podpiszemy nasz request wygenerowanym przez nas wcześniej kluczem prywatnym tworzac tzw. SelfSigned Certificate. Aby to zrobić potrzebne jest takie polecenie:

openssl x509 -req -days 365 -in request.csr \
 -signkey priv.key -out certificate.crt

Tak oto wygenerowaliśmy certyfikat certificate.crt ważny przez 365 dni (tutaj dowolność ustawień ale 1 rok to sensowny okres).

Właściwości certyfikatu można sprawdzić np. tak:

openssl x509 -noout -text -in certificate.crt

Tworzenie własnego CA

Najpierw należy utworzyć klucz prywatny naszego CA, robi się to dokładnie tak samo jak w przypadku generowanego wcześniej klucza prywatnego dla serwera. Później musimy wygenerować requesta (analogicznie jak w przypadku certyfikatu SelfSigned). Czyli dwa polecenia:

openssl genrsa -aes256 -out ca.key 4096
openssl req -new -x509 -days 365 \
 -key ca.key -out ca.crt

Skoro mamy już certyfikat naszego CA, możemy podpisać wcześniej wygenerowany Request dla serwera:

openssl x509 -req -days 365 -in request.csr -CA ca.crt \
 -CAkey ca.key -set_serial 01 -out certificate.crt

Ogólnie podpisywanie przebiega podobnie jak przy certyfikatach SelfSigned ale jak widać wykorzystywane są klucze naszego CA i pojawia się nowy parametr: set_serial, którego wartość musi być inna dla każdego podpisanego przez to CA certyfikatu. Najprościej aby serial przyjmował numer kolejno wygenerowanego certyfikatu.

Jeżeli wiemy, że będziemy generować więcej tego typu certyfikatów warto przygotować sobie skrypt, który zadba o prawidłową wartość pola serial.

Podsumowanie

Certyfikaty przygotowane w ten sposób można wrzucić do Apache, postfix’a, itd… i w ten sposób szyfrując ruch.