Przechowywanie sekretów w Java

1

Mam desktopową aplikację, która ma się łączyć z jakimś tam RESTowym serwerem. Problemem jest uwierzytelnianie. Mniejsza z tym, czy użyje do tego certyfikatu, czy jakiegoś innego sekretu, muszę gdzieś te dane trzymać. To co oferuje Java w tym zakresie, to plik jks chroniony hasłem, co nie daje kompletnie nic, bo zamiast problemu gdzie trzymać hasło do API, pojawia się problem gdzie trzymać hasło do key store.
Z drugiej strony, systemy operacyjne oferują własne schowki na sekrety i sytuacja jest prosta - użytkownik jest zalogowany w systemie, skarbiec otwarty, niezalogowany - zamknięty, Czy jest jakaś sensowna metoda na wykorzystanie tej funkcji systemu w Javie?

1

IMO częsta praktyka to ustawianie hasła w zmiennych środowiskowych na danej maszynie na której chodzi apka.

1

Pytanie co robić jak ktos może np. ukraść maszynę.

Jak haker ma dostęp do fizycznej maszyny to może zrobić wszystko. Szyfrowanie dysków pomaga

0

Żeby lepiej zobrazować o co mi chodzi przykład jak to robią w .NET:
https://stackoverflow.com/questions/9221245/how-do-i-store-and-retrieve-credentials-from-the-windows-vault-credential-manage

Update: It looks like Microsoft (thankfully) restricted this api more in Windows 10 and it will no longer dump all your passwords so trivially. This is only indication of the change that I have seen:
The contents of the locker are specific to the app or service. Apps and services don't have access to credentials associated with other apps or services.

Mogę oczywiście użyć JNI, żeby wykorzystać API Windows, tylko co z Linux, MacOS itd. Trochę mnie dziwi i wkurza, że taka dość oczywista funkcjonalność nie jest ogarnięta na poziomie Java API.

2

Ale czemu nie trzymać hasła po prostu w user.home? ma dostęp zalogowany użytkownik, w każdym sytemie jest odpowiednik.

2

Dlatego ludzie wymyślili podwójną autentykację. Nie jesteś wstanie zabezpieczyć się na 100% przed ludzką głupotą. Zawsze ktoś może pobrać malware albo "zgubić" komputer.

0

@piotrpo: Dane są zapisywane na dysku czy pobierane ? Jakiego typu to jest aplikacja jakiś POS bez userów czy jakis fat client z użytkownikami. Ja widzę tutaj podwójne szyfrowanie raz kluczem który trzymasz na komputerze a dwa wartością dostarczana przez użytkownika czy to w formie hasła/pendriva z kluczem/smart card.

0

Może KeePass, który ma API Javowe.

0

Dane są zapisywane na dysku. Mogę teoretycznie szyfrować dane hasłem dostarczonym przez użytkownika, ale wolałbym użyć gotowego mechanizmu, który w przypadku Windows i MacOS jest wbudowany w system, niż pakować się w rozwój całkiem sporej funkcjonalności (co jak jest więcej niż jeden użytkownik, co jak zapomni hasła, co jak administrator chce mieć jakąś kontrolę nad kontami itd).

2

muszę gdzieś te dane trzymać.

A na pewno musisz? Taki pomysł mi przyszedł do głowy (ale czuję, że zaraz zostanie on zjechany ;) ) - nie trzymasz niczego lokalnie, wszystko pobierasz z serwera. To znaczy - po włączeniu apki łączysz się z serwerem. W ustawieniach klienta masz jedynie podany adres serwera i nic więcej, żadnych danych do bazy czy innych podobnych niejawnych rzeczy.

Użytkownik podaje login i hasło, a te dane lecą na serwer. Jeśli są OK to serwer w odpowiedzi zwraca login i hasło dające dostęp do bazy/serwera/SQL/czegokolwiek innego czy jakiś klucz do odszyfrowania danych trzymanych na dysku. Ty te dane trzymasz w jakichś zmiennych w ramach odpalonej instancji aplikacji, nigdzie to nie ląduje na dysku, po zamknięciu aplikacji wszystko znika.

Co o tym sądzicie, jakie są słabe strony tego rozwiązania?

3

@cerrato:

A na pewno musisz?

Pytanie co chce biznes. Coś czuję, że chcą w aplikacji ptaszka "zachowaj dane uwierzytelniające" ;)

Można zrobić tak, że dane do uwierzytelnienia trzymać np. pod Linuksem w KDE/GNOME Wallet https://github.com/purejava/kdewallet
Pod Mac też jest coś takiego ale nie mam pojęcia jak to zrobić pod windows :)

0

@.andy: W Windows jest Credential Manager. Tak na prawdę, brakuje tylko jakiejś fasady, która spowoduje, że przestanę być zmuszony do grzebania się w JNI do zrobienia prostej rzeczy i zastanawiania się, czy w aktualnej sytuacji powinienem wziąć jakieś dll, so, czy coś jeszcze innego. Czyli potrzebuję żęby "ktoś" zrobił JSR, a później ktoś to zaimplementował :D
To co znalazłem jeżeli chodzi o Windows to https://github.com/dariusz-szczepaniak/java.jna.WindowsCredentialManager

@cerato Nie zjadę cię. Java to obecnie w 99% język serwerowy, gdzie taki problem nie występuje, bo mamy własny serwer, kontrolujemy dostęp do niego, trzymamy w zamkniętej sieci z 5 perymetrami i wszystko co trzeba zrobić, to nie opublikować poufnych danych przez wypchnięcie ich do repo (co też czasami się nie udaje, ale to już szczegół). Natomiast w momencie gdy ktoś chce zrobić aplikację desktopową, to zaczyna się jazda i problemy.

Dane trzymam lokalnie, nie zawsze mam dostęp do Internetu (taka specyfika branży), ale to akurat pomijalny szczegół, bo oczywiście mogę prosić użytkownika o przechowywanie w głowie sekretu, którego później użyję do odszyfrowania kontenera danych z resztą potrzebnych wartości. Mogę wrzucić w instrukcję dla administratora, że aplikacja musi trzymać dane na zaszyfrowanym dysku. Tylko to jest jakaś tam niedogodność, do której ani administratora, ani użytkownika nie chcę zmuszać, a z drugiej strony trzymanie np. certyfikatu niezabezpieczonego hasłem na dysku jest poniżej poziomu bezpieczeństwa, którego potrzebuję. Przykład który wszyscy znają: Slack. Logujesz się do aplikacji raz, aplikacja pozyskuje długo żyjący token i zapisuje go sobie w Credential Manager (wiem, bo przeglądałem właśnie zawartość). Dzięki temu nie jesteś zmuszany za każdym razem do wprowadzenia użytkownika i hasła do aplikacji, bo wystarczy, że potwierdzisz swoją tożsamość logując się na konto w systemie operacyjnym. W przyszłości będzie się logował jak mu wygodnie - wpisze hasło, ustawi PIN, albo zarejestruje palec. Jest bezpiecznie (nawet w przypadku "głupiego" użytkownika), jest wygodnie. Teraz sobie wyobraź, że przy każdym restarcie aplikacji musisz wprowadzić hasła w n aplikacjach, z których każda ma inne wymagania co do złożoności hasła, czasu ważności itd.

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