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

Kodowanie haseł

Object Storage Arubacloud
0 głosów
797 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 (270,190 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 (270,190 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 (270,190 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ź 294 wizyt
pytanie zadane 2 grudnia 2021 w Bezpieczeństwo, hacking przez KILLUMINATI Nowicjusz (130 p.)
0 głosów
1 odpowiedź 358 wizyt
0 głosów
1 odpowiedź 750 wizyt
pytanie zadane 21 lipca 2021 w Bezpieczeństwo, hacking przez sisOOO Obywatel (1,370 p.)

92,579 zapytań

141,431 odpowiedzi

319,657 komentarzy

61,963 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

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy 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!

...