Spring Security, wykorzystanie hasła jako klucz

Odpowiedz Nowy wątek
2018-11-13 23:56
0

Cześć

Tworzę aplikacje webową, która w założeniu ma być odporna na różne ataki i podatności, które są uwzględnione w liście TOP10 OWASP. W tym momencie walczę z "Sensitive Data Exposure". W celu prewencji, planuję zaszyfrować takie dane jak hasło użytkownika i jego numer konta. 

O ile z pomocą frameworka Spring Security i algorytmu Bcrypt z hasłem poszło szybko, przyjemnie i bezproblemowo, o tyle z numerem konta jest inaczej. Problem wynika z tego, że chcę aby był on wyświetlany w panelu zalogowanego użytkownika. Funkcja więc nie może być jednokierunkowa, gdyż muszę ją przy wyświetleniu odszyfrować. 

W celu zaszyfrowania numeru konta wymyśliłem że użyję algorytmu AES, gdzie kluczem będzie hasło(w formie jawnej) użytkownika. Jednak hasło w aplikacji jest przechowywane jako szyfrogram. 

Powstaje więc pytanie, czy jest jakaś możliwość przechwycenia i użycia do odszyfrowania numeru konta, wartości hasła wpisywanej w formularzu logowania zanim zostanie przekształcona w szyfrogram? Wykorzystuję panel logowania udostępniony przez Spring Security. 

Może macie jakieś inne pomysły na zaszyfrowanie numeru konta, lub lepszy pomysł na klucz do algorytmu?

Dziękuję za pomoc i zapraszam do dyskusji. 

Pozostało 580 znaków

2018-11-14 00:47
Wesoły Orzeł
0

Re-używanie hasła użytkownika to słaby pomysł - chyba, że nie przewidujesz możliwości zapomnienia i resetu hasła.

Rozwiązania, które znam sprowadzają się do tego, żeby haseł używanych do szyfrowania nie trzymać razem z zaszyfrowanymi danymi (a jak się chce mieć inne hasło dla każdego usera to trzyma się hasła, ale znów zaszyfrowane mocnym algorytmem i klucze do tego algorytmu trzyma się gdzie indziej...)

Czy masz gdzieś może przykład takiego rozwiązania? - panda08690 2018-11-14 00:58

Pozostało 580 znaków

2018-11-14 01:04
1

generalnie chcesz się bronić przed tym że w razie gdy ktoś shakuje Ci serwer to wszyscy użytkownicy nie będą narażeni, ale generalnie nie jesteś w stanie się w 100% zabezpieczyć przed wyciągnięciem danych jednego użytkownika jeśli ktoś się mocno uprze (chyba że Ty też nie będziesz w stanie ich odszyfrować).

Przykładowo możesz zrobić tak:

  • do szyfrowania danych użyj AES-128 albo AES-256, używać trybu CBC, IV możesz albo ustawić na same 0 albo możesz np wygenerować i trzymać w bazie
  • wygeneruj losowy ciąg bajtów i schowaj go w bazie - nie jest to klucz!
  • jako klucza do AES użyj np. PBKDF2(losowe_bajty, SHA256(haslo)) - SHA256 możesz przyciąć jak będzie za długie (możesz też użyć inny algorytm, poczytaj o key derivation) - parametry do Twojego algorytmu (np liczba rund) zapisz w bazie. Zamiast hasla mozesz uzyc czegokolwiek czego nie trzymasz kolo losowych bajtow

najbezpieczniejszą opcją jest taki zestaw* (tylko uzytkownik jest w stanie odszyfrowac - nawet Ty nie jestes w stanie):

  • użytkownik ma klucz prywatny u siebie na komputerze
  • ty w bazie trzymasz klucz publiczny
  • dane wysylane sa do uzytkownika w postaci zaszyfrowanej
  • uzytkownik szyfruje dane i wysyla Ci dane i haslo zaszyfrowane za pomocą klucza publicznego (z podkreśleniem na publiczny) - tylko osoba z kluczem prywatnym jest w stanie takie haslo odszyfrowac (czyli uzytkownik)

* zakładając że nie masz problemów z XSS na stronie, ale wtedy chyba już nic nie pomoże

generalnie taki format jest opisany w standardzie CMS [Cryptographic Message Syntax] (nie znam API to javy, ale zakładam że ma gdzieś coś takiego). Używaj tylko z AES w kombinacji z RSA lub ECC


░█░█░█░█░█░█░█░█░█░█░█░
edytowany 5x, ostatnio: krwq, 2018-11-14 01:15
Pokaż pozostałe 4 komentarze
PBKDF2(losowe_bajty, SHA256(haslo)) a gdzie iteracje? - WeiXiao 2018-11-14 22:05
Okej, wydaje mi się że rozumiem tę kwestie. Ale teraz pytanie. Czy przechowywanie obu argumentów funkcji, na bazie, jest bezpieczne? Przecież przy wypłynięciu danych nic nie stoi na przeszkodzie samemu odczytać sobie klucz. Btw. do hashowania hasła używam algorytmu BCrypt, rozumiem, że on się nada? - panda08690 2018-11-15 13:36
@panda08690: hash_function(salt, real_plain_password) = hash. Mając hash i salt (bo to się trzyma w bazie) nie odwrócisz tej funkcji żeby wyciągnąć hasło, więc musisz sprawdzać, a to może być bardzo kosztowne (lata), ale najlepiej gdybyś pytał jakiegoś koxa o te sprawy :) - WeiXiao 2018-11-15 18:11
@WeiXiao - nie chciałem komplikować głównej idei, wspomniałem o tym w poście. @panda08690 tak jak napisałem w poście - nie da się zabezpieczyć przed shakowaniem pojedynczego użytkownika, da się tylko ograniczyć szkody - PBKDF2 jest na tyle wolny że brute force hasła jak i sprawdzanie wszystkich naraz jest upierdliwy. Postaraj się po prostu nie trzymać wszystkich parametrów do PBKDF2 obok siebie w bazie (np hasło czy hash hasła możesz spytać jeszcze raz użytkownika przed operacją na której Ci zależy albo trzymać jakiś inny hash w ciasteczku) - krwq 2018-11-15 19:04
inny hash, czyli to co napisał @WeiXiao, z tym że jako implementacji hash_function użyj HMAC_<HASH FUNC> - np. HMAC_SHA256. (np. przy logowaniu wygenerować ciasteczko z bajtami opartymi na haśle np.: HMAC_SHA256(haslo, nazwa_uzytkownika)) - krwq 2018-11-15 19:06

Pozostało 580 znaków

2018-11-15 14:03
0

A może ma ktoś jakiś inny pomysł jak zaszyfrować tę daną na bazie? Może jakieś sprytne przechowywanie kluczy?
Zależy mi na tym, aby użytkownik po wpisaniu hasła od razu mógł zobaczyć odszyfrowaną wartość numeru konta bankowego, nie musiał wpisywać dodatkowych haseł, które musiałby zapamiętać.

@panda08690 nikt nie powiedział że crypto jest łatwe :P - krwq 2018-11-15 19:10

Pozostało 580 znaków

2018-11-15 18:12
0

@panda08690:

A gdyby rozdzielić login do konta i numer konta bankowego?

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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