• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Kodowanie haseł

VPS Starter Arubacloud
0 głosów
778 wizyt
pytanie zadane 13 sierpnia 2020 w Java przez Szyszka Gaduła (3,490 p.)

Witam. Jakie są różnice między haszowaniem a kodowaniem? W jaki sposób mogę poprawnie używać zakodowanego hasła? Gdy takie hasło zakodowane zapisze:

       @PostMapping
       @Transactional
       @Modifying
       public void saveAccountData(Account account, Model model) {
              PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
              if(accountRepository.takeAllNames().toString().indexOf(account.getNick()) != -1) {
                     model.addAttribute("registerResponse", "Podana nazwa użytkownika jest zajęta!");
              }
              else{
                     model.addAttribute("registerResponse", account.getNick() + ", zostałeś pomyślnie zarejestrowany!");
                     //accountRepository.save(account);
                     entityManager.createNativeQuery("INSERT INTO KONTA (ID, NAZWA, HASŁO) VALUES(:id, :nick, :password)")
                     .setParameter("id", account.getId())
                     .setParameter("nick", account.getNick())
                     .setParameter("password", passwordEncoder.encode(account.getPassword()))
                     .executeUpdate();
                     log.info("Zarejestrowano konto o nazwie: " + account.getNick());
              }
       }

To mam zakodowane hasło w bazie H2. Lecz kiedy chcę się zalogować na konto, to muszę użyć tych właśnie znaków powstałych po zakodowaniu. Próbowałem przy logowaniu do ifa dodać, czy jeśli zakoduję podane hasło, to będzie się równać temu zakodowanemu w bazie. Jednak te hasła zawsze kodują się inaczej :/.

       @PostMapping
       @Transactional
       @Modifying
       public void login(Account account, Model model){
              PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
              Query query = entityManager.createNativeQuery("SELECT HASŁO FROM KONTA WHERE NAZWA = :name");
              query.setParameter("name", account.getNick());
              if((accountRepository.takeAllNames().toString().indexOf(account.getNick()) == -1) || (!query.getSingleResult().equals(passwordEncoder.encode(account.getPassword())))){
                     model.addAttribute("loginResponse", "Błędna nazwa użytkownika lub hasło");
              }
              else if(query.getSingleResult().toString().equals(account.getPassword())){
                     model.addAttribute("loginResponse", "Udało się zalogować, dane poprawne");
              }
       }

Jak mam tej magii dokonać?

komentarz 13 sierpnia 2020 przez Wiciorny Ekspert (269,120 p.)

jeszcze mała dygresja 

@Modifying
public void login

@Modyfing nie stosujesz przy SELECT, nie wrzucaj "na pałe czegoś co spełnia jakąs konkretną rzecz, w tym wypadku FLAGE o informacji zmian - na bazie, select zmiany nie wywołuje
 

2 odpowiedzi

0 głosów
odpowiedź 13 sierpnia 2020 przez Wiciorny Ekspert (269,120 p.)
wybrane 13 sierpnia 2020 przez Szyszka
 
Najlepsza
passwordEncoder.encode(account.getPassword()))

W metodzie zapisywania do bazy danych "kodujesz hasło" - > Kodowanie czyli  zapisujesz hasło w postaci jakiegoś wygenerowanego kodu. Okej? Odp. sobie na pytanie jak teraz wiedzieć, że zapisane hasło odpowiada danemu zapisowi ? A no ... bo według metod  wywołanie metody equals  po wykonaniach operacji powinno zwrócić true- no ale equals Koszysta z haszu? co jeśli 2 konta mają to samo hasło, co może się zdarzyć? Jak komputer ma wtedy rozróżnić te dwie rzeczy ? 
Dlatego HASH- jest indywidualnie przypisywany na obiekt, wtedy masz pewność że pod danym hashem jest wystąpienie np jakiegoś kodowania hasła, i  taki obiekt mający indywidualny HASH - HASŁO jest jednoznacznie odwzorowany.

Więc pan Login1 z hasłem : dupa - będzie innym obiektem niż Login2 - z hasłem dupa 
i to właśnie uzyskujesz dzieki HASHOWANIU. 

 

 PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

Ja bym to wydzielił do pola klasy? Za każdym razem tworzysz nową instancje kodowania... dlatego możesz mieć problem :) zarówno na każdy login, jak i zapis.

Pobierasz hasło z bazy danych 

"SELECT HASŁO FROM KONTA WHERE NAZWA = :name"

a potem znowu je KODUJESZ? :) masz je zdekodować 

 

Pierwsza linia? znowu encode- password? czyli pobierasz zakodowane hasło z bazy, i porównujesz czy jest ono takie samo? tylko żę to dwa inne obiekty...  

(!query.getSingleResult().equals(passwordEncoder.encode(account.getPassword()))))
query.getSingleResult().toString().equals(account.getPassword())

a tutaj co się dzieje ? Wykonujesz na bazie zapytanie, otrzymałeś ZAKODOWANE HASŁO i porównujesz czy jest ono zgodne z hasłem dla użytkownika, no nie jest... bo nie zdekodowałeś go.

https://www.baeldung.com/java-base64-encode-and-decode 
zapomniałeś o dekodowaniu ;] hasła, zakodowanego. Przemyśl implementacje raz jeszcze 

komentarz 13 sierpnia 2020 przez Szyszka Gaduła (3,490 p.)

Okej. hashCode nigdy nie wiedziałem po co używać, i teraz też nie wiem, bo przecież w zapytaniu wskazuje które hasło ma wziąć z bazy danych. Ogółem, to obczaiłem teraz metodę matches(), która świetnie się sprawuje :D. @Modifying to racja, zbędne, zapomniałem tego wywalić po zabawie z insert into. Mógł byś ocenić, czy takie coś:

       @PostMapping
       @Transactional
       public void login(Account account, Model model){
              Query query = entityManager.createNativeQuery("SELECT HASŁO FROM KONTA WHERE NAZWA = :name");
              query.setParameter("name", account.getNick());
              if((accountRepository.takeAllNames().toString().indexOf(account.getNick()) == -1) || (!passwordEncoder.matches(account.getPassword(), query.getSingleResult().toString()))){
                     model.addAttribute("loginResponse", "Błędna nazwa użytkownika lub hasło");
              }
              else if(passwordEncoder.matches(account.getPassword(), query.getSingleResult().toString())){
                     model.addAttribute("loginResponse", "Udało się zalogować, dane poprawne");
              }
       }

Jest bezpieczne? I dał byś może jakiś przykład z wykorzystaniem equals oraz hashCode?

 

komentarz 13 sierpnia 2020 przez Wiciorny Ekspert (269,120 p.)

dokumentacja metod które używasz... jak czegoś używasz to sprawdzaj jak wygląda to wewnętrzenie... a nie na pałe korzystaj z metod. Naucz się korzystać z czegoś samodzielnie, myśl... 
https://stackoverflow.com/questions/326699/difference-between-hashing-a-password-and-encrypting-it
wystarczy stuknąć w google i przeczytać, a to samo zrobić co do - EQUALS AND HASHCODE 

0 głosów
odpowiedź 13 sierpnia 2020 przez mbabane Szeryf (79,280 p.)

Nie jest bezpiecznie ponieważ pobierasz hasło z bazy danych.

Query query = entityManager.createNativeQuery("SELECT HASŁO FROM KONTA WHERE NAZWA = :name");

Jeśli chcesz zaimplementować logowanie ręcznie to zrób w ten sposób, że hasujesz otrzymane od użytkownika hasło następnie robisz select'a po username i haszu hasła. Jeśli znajdzie to oznacza że użytkownik podał poprawne dane. (I w sumie też wydaje mi się, że nie potrzebnie tutaj stosujesz NativeQuery). (Można tutaj zastosować exists z repository: https://www.baeldung.com/spring-data-exists-query )

(Hasło w bazie ma być przechowywane jako hash i to ma działać w jedną stronę, czyli jeśli masz hash hasla to nie jesteś w stanie go zdekodować/odhaszowac).

Wygląda jakbyś używał springa, więc najlepiej wziąć Spring security.

Podobne pytania

+1 głos
1 odpowiedź 274 wizyt
pytanie zadane 2 grudnia 2021 w Bezpieczeństwo, hacking przez KILLUMINATI Nowicjusz (130 p.)
0 głosów
1 odpowiedź 334 wizyt
0 głosów
1 odpowiedź 689 wizyt
pytanie zadane 21 lipca 2021 w Bezpieczeństwo, hacking przez sisOOO Obywatel (1,370 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...