2011-07-12 13 views
5

Chciałbym zaszyfrować dane, które wędrują tam iz powrotem między serwerem a klientem w mojej aplikacji internetowej. Używałbym SSL, ale to wymaga certyfikatu wraz z dedykowanym adresem IP. Nie mam problemu z uzyskaniem certyfikatu, ale dedykowany adres IP wymaga ode mnie uaktualnienia do planu hostingu biznesowego, który wynosi 20 USD miesięcznie na moim hoście internetowym. Nie planuję tego robić, ponieważ trzymam się mojego wspólnego planu hostingu o wartości 20 USD rocznie.Alternatywa dla SSL - szyfrowanie "ręczne"?

Chciałbym więc wprowadzić alternatywę dla SSL. Jednak robi to więcej niż SSL. Wraz z szyfrowaniem danych przesyłanych tam iz powrotem, szyfruje również wiersze w bazie danych. Myślałam o zrobienie czegoś takiego:

kod JavaScript:

var transfer_key = 'whatever'; 
function encrypt(data, key) {...} 
function decrypt(data, key) {...} 

function send_data_to_server(url, data) 
{ 
    $.post(url, {'data' : encrypt(data, transfer_key) }, function(response) { 
     var decrypted_response = JSON.parse(decrypt(response)); 
    }); 
} 

Kod PHP:

$data = $_POST['data']; 
$transfer_key = 'whatever'; 
$storage_key = 'whatever2'; 

function encrypt($data, $key) {...} 
function decrypt($data, $key) {...} 

databaseQuery('INSERT INTO table VALUES (?)', encrypt($data, $storage_key)); 

$decrypted_data = decrypt($data, $transfer_key); 
$response = processData($decrypted_data); 

echo encrypt($transfer_key, $response); 

Jak widać, dane klienta wysyłane na serwer jest szyfrowane i na odwrót. A dane w bazie danych są również szyfrowane. Oczywiście, nigdy nie wdrożyłbym takich kluczy. Prawdopodobnie miałbym drugi lub trzeci klucz losowo wygenerowany dla każdego użytkownika. Tak więc klucz_przelewnika może być równy kluczowi stałemu połączonemu z kluczem losowym, a to samo dotyczy klucza_pamięci.

Czy to dobra alternatywa dla SSL? Jak mogę wdrożyć ten rodzaj szyfrowania w taki sposób, że trudniej go pokonać? Czy są jakieś szczególne słabości tego podejścia?

Prawdopodobnie znajdę bibliotekę JS, która zajmie się szyfrowaniem i użyje rozszerzenia PHP mcrypt dla serwera. Myślałem o Blowfish, może AES256, ale nie jestem pewien, który daje mi najlepszy stosunek siły szyfrowania do zużycia pamięci.

Porady?

+2

Nie wiem, że protokół SSL wymaga dedykowanego adresu IP.Ponadto, wiem, że jest to pseudo-kod, ale w tej chwili 'DBData = encrypt (encrypt (clientData, transfer_key), storage_key)' - który, jeśli wskażesz, transfer_key jest efemeryczny w jakiś sposób, oznacza, że ​​nigdy nie możesz odszyfrować dane bazy danych. –

+4

Tak więc, wszystkie ja (jako atakujący) muszę zrobić, to powąchać zwykły ruch html wysyłany do klienta zawierającego kod javascript za pomocą kluczy szyfrujących/odszyfrowujących. miło ... Poważnie, trzymaj się SSL/TLS – NotMe

+1

@Damien_The_Unbeliever: SSL samo w sobie nie; ale jego dostawca może pakować to w ramach droższego planu. – NotMe

Odpowiedz

41

Uh, oh. Powodzenia z tym. Czy spojrzałeś na TLS specification? Czy uważasz, że możesz wymyślić coś odpowiedniego, co zostanie sprawdzone przez miliony ludzi?

Nie, naprawdę, TLS został przetestowany i udoskonalony przez wiele lat przez tak wielu ludzi, kryptografów, którzy nie robią nic poza łamaniem takich protokołów, byłoby ciężkim zadaniem wymyślanie czegoś odpowiedniego.

SSL został opracowany przez ekspertów w tej dziedzinie i na pewno z początku pomyślał też, że ich protokół jest absolutnie nie do złamania. Ale wtedy była wersja 2, potem 3, potem TLS v.1, v1.1 i teraz 1.2.

Jeśli nie masz wcześniejszego doświadczenia w projektowaniu bezpiecznych protokołów, powinieneś trzymać się głównego nurtu i używać TLS/SSL.

Bezpieczeństwo to jedno z nielicznych dziedzin, w którym ma sens i fajnie jest iść z głównym nurtem, więc powiedziałbym, że dodatkowe pieniądze byłyby dobrze wydane.

Edit:

Może byłem nieco szorstki, i brakowało mi jakieś wyjaśnienie, dlaczego podejście nie może konkurować z nieco skomplikowanym protokołem takich jak TLS, więc przeanalizujmy go:

1) Jak czy zrobiłbyś kluczową wymianę? Aby AES działał na obu końcach, musisz wykonać kodowanie Key Exchange, aby szyfrowanie symetryczne obie strony musiały posiadać ten sam klucz. Jak powiedziałeś, chciałbyś wygenerować go losowo na kliencie - na razie tak dobrze. Pierwszy problem - musisz wygenerować secure random number - w przeciwnym razie, np. za pomocą wbudowanego generatora liczb losowych JavaScript - napastnicy będą w stanie przewidzieć losowe liczby po pewnym czasie.

2) Powiedzmy, że masz to opanowane. Następnie pojawia się kolejny problem, w jaki sposób wysłałby ten klucz do serwera w bezpieczny sposób, tj. Wykonał wymianę klucza? Nie będzie trzeba jakąś formę uwierzytelniania po stronie serwera, w przeciwnym razie po prostu o każdy może narzucić jako serwer i to zrobić:

  • sztuczka ludzi do wysyłania ich klucze do ich fałszywych pierwszej
  • następnie przekazuje klucz serwera do serwera
  • serwer będzie sumiennie wysyłać dane zaszyfrowane przy ustalonych kluczowych
  • atakujących będzie przechwytywać te dane i szczęśliwie czytać swoje tajemnice przez odszyfrowanie za pomocą klucza po prostu ukradł

3) Potrzebne jest zatem uwierzytelnienie serwera, przynajmniej jeśli nie jest to uwierzytelnianie klienta. Będzie to oznaczać, że potrzebujesz jakiejś formy kryptografii z kluczem asymetrycznym/kluczem publicznym, aby zaszyfrować/opakować klucz za pomocą klucza publicznego serwera, tak aby serwer mógł go odszyfrować.

4) Po opanowaniu, że jesteś jeszcze bardziej podatne na ataki zaangażowanych form takich jak replay attacks, man-in-the-middle-attacks, reflection attacks ...

5) Może również chcesz Perfect Forward Secrecy tak, że gdy klucz robi włamać się do ataku, osoba atakująca nie będzie w stanie odszyfrować żadnych przeszłych danych. Będziesz potrzebował Diffie-Hellman (najlepiej w swoim formularzu Elliptic Curve Cryptography), aby to osiągnąć.

6) Ostatni, ale nie mniej ważny mechanizm sesji prawdopodobnie byłby również przyjemny, dzięki czemu można odebrać poprzednie sesje z już ustanowionymi kluczami symetrycznymi, dzięki czemu można zmniejszyć obciążenie serwera bez konieczności ponownego ustanawiania to znowu przy użyciu algorytmów klucza publicznego, które wymagają nieco zasobów.

-> Dodaj jeszcze kilka dodatkowych funkcji, takich jak bezpieczne negocjowanie pakietu algorytmów, które potwierdzają zarówno klient, jak i serwer, a także zostanie wdrożony ponownie protokół TLS.

Przepraszam, jeśli to brzmi trochę sarkastycznie, ale wiem, że wydaje się kuszące toczenie własnych schematów kryptograficznych (to także fajne), ale ostatecznie powinieneś trzymać się TLS: jest to (względnie) łatwe w użyciu, działa na warstwie transportowej (dzięki czemu możesz kodować aplikacje tak, jakby nie było w ogóle szyfrowania), a co najważniejsze, jest bezpieczny.

EDIT: Cóż, były pewne ataki niedawno, ale prawie wszystkie ataki eksploatowane „czynnika ludzkiego” w tych protokołach atakując certyfikatów klucza publicznego, który kopii protokołu (Comodo, DigiNotar etc.to są wybitne przykłady) lub bardziej tajemnicze funkcje protokołu, takie jak negocjacja algorytmu itp., ale BEAST był pierwszym razem, gdy TLS został skutecznie zaatakowany na poziomie kryptografii, co jest interesujące i przerażające w tym samym czasie, ponieważ podstawy ten atak znany jest teraz od some years.

Wciąż z ostatnimi poprawkami do BEAST, założę się, że TLS to wciąż najlepsza opcja dla bezpiecznej komunikacji w sieci, szczególnie w porównaniu do ręcznie wykonanych rozwiązań.

+10

+1: Przestałem czytać po tym, jak zobaczyłem kod javascript z szyfrowaniem/odszyfrowywaniem i kluczami .. – NotMe

+5

+1. Zasada # 1 dotycząca pisania własnego schematu szyfrowania: Nie rób tego. –

+0

Chciałbym dać +1 ponownie. Świetne napisz. – NotMe

3

Moja rada to trzymać się SSL/TLS. Myślę, że to ułatwi Ci życie, a także da Twojej branży rozwiązanie uznanej wiarygodności.

Zamiast statycznego adresu IP, czy można użyć usługi DynDNS (lub podobnej usługi) z samopodpisanym certyfikatem?

9

Ryan: Mówię to w nadziei, że to najlepszy możliwy sposób: zużycie pamięci jest absolutnie najmniejszym problemem.

Nie ma nic bezpiecznego w tym zakresie. Nic. N.o.t.h.i.n.g.

Jest martwy od pierwszego wysłania tego javascriptu ... Nie obchodzi mnie, jak długo są twoje klucze i jak losowa jest sól.

To, co masz, nie powstrzyma kogoś siedzącego w kawiarni przy otwartym laptopie, który nie będzie przechwytywał pakietów od przechwytywania kluczy i będzie w stanie odszyfrować wszystko, co przejedziesz tam iz powrotem. Heck, samo zobaczenie słów "zaszyfrować", "odszyfrować" i "klucz" w strumieniu wystarczyłoby, by wzbudzić zainteresowanie kogoś, aby zanurkować dalej dla zabawy (lub zysku ...). Nieważne, że oglądanie otwartego połączenia nagle rozpocznie przesyłanie części zaszyfrowanych pakietów i innych części w czysty sposób.

Jeśli to, co masz, jest warte zaszyfrowania, to warte dodatkowych 240 USD rocznie, aby zrobić to dobrze. Proszę, wycofaj się z półki i zrób to dobrze.

5

Każdy jest tak negatywny, a jednocześnie podzielam sentymentu że osobiście powinien prawdopodobnie nie robi tego, pozwól mi zrobić kilka ogólnych uwag:

do bezpiecznego kanału potrzebne są trzy rzeczy:

  • szyfrowanie linia
  • wymiana kluczy
  • uwierzytelniania

Do szyfrowania należy zaimplementować szyfr. To możliwe.

Kluczowa wymiana to kluczowy punkt: obaj partnerzy muszą wiedzieć, że znają wspólny klucz, a nikt inny nie jest w stanie poznać wspólnego klucza. Istnieją na to protokoły i powinno być możliwe ich wdrożenie. SSL robi to, na przykład. Fakt, że można wyczuć połączenie SSL i niczego się nie nauczyć, pokazuje, że można to zrobić.

Uwierzytelnienie jest konieczne, aby zatrzymać ataki typu "człowiek w środku", a to wymaga jakiejś pozapasmowej wymiany informacji (takiej jak połączenie telefoniczne lub infrastruktura PKI). To, czy coś naprawdę działa, jest wysoce dyskusyjne, nawet w przypadku SSL.

Więc jeśli możesz zaimplementować wszystkie te komponenty przez HTTP, to w zasadzie powinna być możliwa bezpieczna komunikacja przez HTTP. W końcu SSL robi to samo, działa bezpieczny kanał na niebezpiecznym medium. Zasadniczo chcesz zaimplementować SSL w JavaScript. Sprawdź aSSL, próbowali czegoś takiego.