Korzystając z protokołu OAuth, potrzebujesz tajnego ciągu znaków uzyskanego z usługi, do której chcesz delegować. Jeśli robisz to w aplikacji internetowej, możesz po prostu przechowywać sekret w swojej bazie danych lub w systemie plików, ale jaki jest najlepszy sposób obsługi tego w aplikacji mobilnej (lub aplikacji komputerowej)?
Przechowywanie ciągu znaków w aplikacji oczywiście nie jest dobre, ponieważ ktoś mógłby go łatwo znaleźć i wykorzystać.
Innym podejściem byłoby przechowywanie go na serwerze i pobieranie go przez aplikację przy każdym uruchomieniu, nigdy nie zapisując go w telefonie. Jest to prawie tak samo złe, ponieważ musisz podać adres URL w aplikacji.
Jedynym wykonalnym rozwiązaniem, które mogę wymyślić, jest najpierw uzyskanie tokena dostępu w normalny sposób (najlepiej za pomocą widoku internetowego w aplikacji), a następnie skierowanie całej dalszej komunikacji przez nasz serwer, który doda sekret do danych żądania i komunikuje się z dostawcą. Z drugiej strony jestem noobem bezpieczeństwa, więc naprawdę chciałbym usłyszeć opinie niektórych znających się na rzeczy ludzi na ten temat. Nie wydaje mi się, żeby większość aplikacji robiła takie kroki, aby zagwarantować bezpieczeństwo (na przykład Facebook Connect wydaje się zakładać, że umieszczasz sekret w ciągu bezpośrednio w aplikacji).
Inna sprawa: nie wierzę, że tajemnica jest związana z początkowym żądaniem tokena dostępu, więc można to zrobić bez angażowania naszego własnego serwera. Mam rację?
Odpowiedzi:
Tak, jest to problem związany z projektem protokołu OAuth, przed którym stoimy. Zdecydowaliśmy się na proxy wszystkich połączeń przez nasz własny serwer. OAuth nie został całkowicie usunięty z aplikacji komputerowych. Nie ma idealnego rozwiązania problemu, który znalazłem, bez zmiany protokołu OAuth.
Jeśli zastanowisz się nad tym i zadasz pytanie, dlaczego mamy tajemnice, to głównie do udostępniania i wyłączania aplikacji. Jeśli nasz sekret zostanie ujawniony, dostawca może naprawdę odwołać tylko całą aplikację. Ponieważ musimy osadzić nasz sekret w aplikacji komputerowej, jesteśmy trochę pokręceni.
Rozwiązaniem jest posiadanie innego sekretu dla każdej aplikacji komputerowej. OAuth nie ułatwia tej koncepcji. Jednym ze sposobów jest poproszenie użytkownika o samodzielne utworzenie sekretu i samodzielne wprowadzenie klucza do aplikacji komputerowej (niektóre aplikacje Facebooka robiły coś podobnego przez długi czas, zmuszając użytkownika do tworzenia Facebooka, aby skonfigurować własne quizy i bzdury). To nie jest wspaniałe doświadczenie dla użytkownika.
Pracuję nad propozycją systemu delegowania OAuth. Pomysł polega na tym, że używając naszego własnego tajnego klucza, który otrzymujemy od naszego dostawcy, możemy wydać nasz własny delegowany sekret naszym własnym klientom komputerowym (w zasadzie po jednym dla każdej aplikacji komputerowej), a następnie podczas procesu uwierzytelniania wysyłamy ten klucz na najwyższy poziom dostawca, który oddzwania do nas i ponownie dokonuje weryfikacji u nas. W ten sposób możemy unieważnić własne sekrety, które wysyłamy do każdego klienta desktopowego. (Pożyczanie tego, jak to działa z SSL). Cały ten system byłby idealny także dla usług sieciowych o wartości dodanej, które przekazują wywołania do usług sieciowych strony trzeciej.
Proces można również wykonać bez wywołań zwrotnych weryfikacji delegacji, jeśli dostawca najwyższego poziomu udostępnia interfejs API do generowania i odwoływania nowych delegowanych wpisów tajnych. Facebook robi coś podobnego, zezwalając aplikacjom Facebooka, aby umożliwić użytkownikom tworzenie podaplikacji.
W Internecie jest kilka rozmów na temat tego problemu:
http://blog.atebits.com/2009/02/fixing-oauth/ http://groups.google.com/group/twitter-development-talk/browse_thread/thread/629b03475a3d78a1/de1071bf4b820c14#de1071bf4b820c14
Rozwiązaniem Twittera i Yammera jest kod PIN uwierzytelniania: https://dev.twitter.com/oauth/pin-based https://www.yammer.com/api_oauth_security_addendum.html
źródło
Dzięki OAUth 2.0 możesz przechowywać sekret na serwerze. Użyj serwera, aby uzyskać token dostępu, który następnie przeniesiesz do aplikacji i możesz bezpośrednio wykonywać połączenia z aplikacji do zasobu.
W przypadku OAuth 1.0 (Twitter) do wykonywania wywołań API wymagany jest sekret. Proxowanie połączeń przez serwer to jedyny sposób na zapewnienie, że sekret nie zostanie naruszony.
Obydwa wymagają pewnego mechanizmu, dzięki któremu komponent serwera wie, że dzwoni do niego klient. Zwykle dzieje się to podczas instalacji i przy użyciu mechanizmu specyficznego dla platformy, aby uzyskać identyfikator aplikacji w wywołaniu serwera.
(Jestem redaktorem specyfikacji OAuth 2.0)
źródło
Jednym z rozwiązań może być trwałe zakodowanie klucza OAuth w kodzie, ale nie jako zwykły ciąg. W jakiś sposób zaciemnij to - podziel na segmenty, przesuń znaki o przesunięcie, obróć - zrób jedną lub wszystkie te rzeczy. Cracker może przeanalizować kod bajtowy i znaleźć ciągi znaków, ale kod zaciemniający może być trudny do odgadnięcia.
To nie jest niezawodne rozwiązanie, ale tanie.
W zależności od wartości exploita, niektórzy genialni crackerzy mogą podjąć większe starania, aby znaleźć Twój tajny kod. Musisz rozważyć czynniki - koszt wcześniej wspomnianego rozwiązania po stronie serwera, zachęty dla crackerów do poświęcenia większej ilości wysiłku na znalezienie tajnego kodu oraz złożoność zaciemniania, które możesz zaimplementować.
źródło
Nie przechowuj sekretu w aplikacji.
Musisz mieć serwer, do którego aplikacja może uzyskać dostęp przez https (oczywiście) i przechowujesz na nim sekret.
Gdy ktoś chce się zalogować za pośrednictwem aplikacji mobilnej / stacjonarnej, Twoja aplikacja po prostu przekaże żądanie do serwera, który następnie dołączy sekret i wyśle go do usługodawcy. Twój serwer może wtedy powiedzieć aplikacji, czy się powiodło, czy nie.
Następnie, jeśli potrzebujesz uzyskać jakiekolwiek poufne informacje z serwisu (facebook, google, twitter, itp.), Aplikacja poprosi twój serwer, a twój serwer przekaże je aplikacji tylko wtedy, gdy jest poprawnie podłączony.
Tak naprawdę nie ma żadnej opcji oprócz przechowywania go na serwerze. Nic po stronie klienta nie jest bezpieczne.
Uwaga
To powiedziawszy, ochroni Cię to tylko przed złośliwym klientem, ale nie przed złośliwym klientem, a nie klientem przed innymi złośliwymi klientami (phishing) ...
OAuth to znacznie lepszy protokół w przeglądarce niż na komputerze / urządzeniu mobilnym.
źródło
Istnieje nowe rozszerzenie typu nadania kodu autoryzacji o nazwie Proof Key for Code Exchange (PKCE) . Dzięki niemu nie potrzebujesz tajemnicy klienta.
z https://oauth.net/2/pkce/
Aby uzyskać więcej informacji, możesz przeczytać pełny dokument RFC 7636 lub to krótkie wprowadzenie .
źródło
Tutaj jest coś do przemyślenia. Google oferuje dwie metody OAuth ... w przypadku aplikacji internetowych, w których rejestrujesz domenę i generujesz unikalny klucz, oraz w przypadku zainstalowanych aplikacji, w których używasz klucza „anonimowy”.
Być może pominąłem coś w tekście, ale wydaje się, że udostępnianie unikalnego klucza aplikacji internetowej z zainstalowaną aplikacją jest prawdopodobnie bezpieczniejsze niż używanie „anonimowości” w oficjalnej metodzie instalowania aplikacji.
źródło
Dzięki OAuth 2.0 możesz po prostu użyć przepływu po stronie klienta, aby uzyskać token dostępu, a następnie użyć tego tokenu dostępu do uwierzytelnienia wszystkich dalszych żądań. Wtedy wcale nie potrzebujesz sekretu.
Ładny opis, jak to wdrożyć, można znaleźć tutaj: https://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified#mobile-apps
źródło
Nie mam dużego doświadczenia z OAuth - ale czy nie każde żądanie wymaga nie tylko tokena dostępu użytkownika, ale także klucza i tajnego klucza klienta aplikacji? Tak więc, nawet jeśli ktoś ukradnie urządzenie mobilne i spróbuje wyciągnąć z niego dane, będzie potrzebował klucza aplikacji i tajnego klucza, aby móc cokolwiek zrobić.
Zawsze myślałem, że intencją OAuth jest to, aby każdy Tom, Dick i Harry, którzy mieli mashup, nie musieli przechowywać Twoich danych uwierzytelniających na Twitterze. Myślę, że pomimo swoich ograniczeń całkiem dobrze rozwiązuje ten problem. Poza tym tak naprawdę nie został zaprojektowany z myślą o iPhonie.
źródło
Zgadzam się z Felixyz. OAuth jest lepszy niż uwierzytelnianie podstawowe, ale wciąż ma długą drogę do znalezienia dobrego rozwiązania dla aplikacji mobilnych. Bawiłem się używaniem OAuth do uwierzytelniania aplikacji telefonu komórkowego w aplikacji Google App Engine. Fakt, że nie można niezawodnie zarządzać tajemnicą klienta na urządzeniu mobilnym, oznacza, że domyślnie jest używany dostęp „anonimowy”.
Etap autoryzacji przeglądarki OAuth w implementacji Google App Engine prowadzi do strony, na której znajduje się tekst w stylu: „Witryna <nazwa-witryna> prosi o dostęp do Twojego konta Google dla produktów wymienionych poniżej”
YourApp (yourapp.appspot.com) - nie jest stowarzyszona z Google
itp
Pobiera <some-site> z nazwy domeny / hosta używanej w adresie URL wywołania zwrotnego, który podasz, który może być dowolną wartością w systemie Android, jeśli używasz niestandardowego schematu do przechwycenia wywołania zwrotnego. Jeśli więc korzystasz z dostępu „anonimowego” lub Twój sekret klienta zostanie naruszony, każdy może napisać konsumenta, który oszuka go, aby dał dostęp do Twojej aplikacji gae.
Strona autoryzacji Google OAuth zawiera również wiele ostrzeżeń, które mają 3 poziomy ważności w zależności od tego, czy używasz klucza „anonimowego”, klucza klienta czy klucza publicznego.
Dość przerażające rzeczy dla przeciętnego użytkownika, który nie jest doświadczony technicznie. Nie spodziewam się wysokiego procentu ukończenia rejestracji przy tego rodzaju rzeczach.
Ten wpis na blogu wyjaśnia, w jaki sposób tajemnice konsumenta tak naprawdę nie działają z zainstalowanymi aplikacjami. http://hueniverse.com/2009/02/should-twitter-discontinue-their-basic-auth-api/
źródło
Próbuję również wymyślić rozwiązanie do mobilnego uwierzytelniania OAuth i ogólnie do przechowywania sekretów w pakiecie aplikacji.
I właśnie uderzył mnie szalony pomysł: najprostszym pomysłem jest przechowywanie sekretu w pliku binarnym, ale w jakiś sposób zaciemniony lub, innymi słowy, przechowywanie zaszyfrowanego sekretu. Oznacza to, że musisz przechowywać klucz, aby odszyfrować swój sekret, co wydaje się, że zatoczyło nas pełne koło. Jednak dlaczego nie użyć po prostu klucza, który jest już w systemie operacyjnym, tj. Jest zdefiniowany przez system operacyjny, a nie przez aplikację.
Więc, aby wyjaśnić mój pomysł, wybierasz ciąg zdefiniowany przez system operacyjny, nie ma znaczenia, który z nich. Następnie zaszyfruj swój sekret, używając tego ciągu jako klucza i zapisz go w swojej aplikacji. Następnie w czasie wykonywania odszyfruj zmienną za pomocą klucza, który jest po prostu stałą systemu operacyjnego. Każdy haker zaglądający do Twojego pliku binarnego zobaczy zaszyfrowany ciąg znaków, ale bez klucza.
Czy to będzie działało?
źródło
Tutaj odpowiadam na bezpieczny sposób przechowywania informacji oAuth w aplikacji mobilnej
https://stackoverflow.com/a/17359809/998483
https://sites.google.com/site/greateindiaclub/mobil-apps/ios/securelystoringoauthkeysiniosapplication
źródło
Facebook nie implementuje protokołu OAuth ściśle mówiąc (jeszcze), ale zaimplementował sposób, abyś nie osadzał swojego sekretu w aplikacji na iPhone'a: https://web.archive.org/web/20091223092924/http://wiki. developers.facebook.com/index.php/Session_Proxy
Jeśli chodzi o OAuth, tak, im więcej o tym myślę, jesteśmy trochę wypchani. Może to to naprawi.
źródło
Żadne z tych rozwiązań nie uniemożliwia zdeterminowanemu hakerowi podsłuchiwania pakietów wysyłanych z urządzenia mobilnego (lub emulatora) w celu wyświetlenia klucza klienta w nagłówkach http.
Jednym z rozwiązań mogłoby być posiadanie dynamicznego hasła, które składa się ze znacznika czasu zaszyfrowanego za pomocą prywatnego dwukierunkowego klucza i algorytmu szyfrowania. Usługa następnie odszyfrowuje sekret i określa, czy znacznik czasu wynosi +/- 5 minut.
W ten sposób, nawet jeśli sekret zostanie ujawniony, haker będzie mógł go używać maksymalnie przez 5 minut.
źródło
Jak wspominali inni, nie powinno być prawdziwego problemu z przechowywaniem sekretu lokalnie na urządzeniu.
Ponadto zawsze możesz polegać na opartym na systemie UNIX modelu zabezpieczeń systemu Android: tylko Twoja aplikacja ma dostęp do tego, co zapisujesz w systemie plików. Po prostu zapisz informacje w domyślnym obiekcie SharedPreferences swojej aplikacji.
Aby uzyskać sekret, należałoby uzyskać uprawnienia roota do telefonu z systemem Android.
źródło