Yalnızca güvenilir mobil uygulamalar için bir REST API'sini nasıl koruyabilirim?


96

Kendi mobil uygulamalarımda REST API’mın yalnızca güvenilir müşteriler tarafından oluşturulan isteklere yanıt verdiğinden nasıl emin olabilirim? İstenmeyen isteklerin diğer kaynaklardan gelmesini önlemek istiyorum. Kullanıcıların seri bir anahtar doldurmalarını ya da her neyse, sahnelerin arkasında, kurulum sırasında ve gerekli herhangi bir kullanıcı etkileşimi olmadan gerçekleşmesini istemiyorum.

Bildiğim kadarıyla, HTTPS sadece iletişim kurduğunuz sunucuyu doğrulamak için kim olduğunu söylüyor. Tabii ki verileri şifrelemek için HTTPS kullanacağım.

Bunu başarmanın bir yolu var mı?

Güncelleme: Kullanıcı, kullanıcının giriş yapmasını gerektirmeyen salt okunur eylemler gerçekleştirebilir, ancak kullanıcının giriş yapmasını gerektiren yazma işlemleri de yapabilir (Erişim Simgesi ile Kimlik Doğrulama). Her iki durumda da, API'nin yalnızca güvenilir mobil uygulamalardan gelen isteklere yanıt vermesini istiyorum.

API, mobil uygulama aracılığıyla yeni bir hesap kaydetmek için de kullanılacaktır.

Güncelleme 2: Bunun birden fazla cevabı var gibi görünüyor, ama dürüstçe hangisini cevaplayacağımı bilmiyorum. Bazıları yapılabileceğini, bazıları yapamadığını söylüyor.


HTTPS, SSL (ve TLS) kullanır. SSL / TLS müşteri kimlik doğrulaması ile kullanılabilir.
atk

İstemci tarafı SSL sertifikaları mı demek istiyorsun? Sanırım aradığım şey bu, mobil uygulamalarda (Android ve iOS) mümkün olsa bile hiçbir fikrim yok. Müşteri sertifikası nerede saklanır? Cihaz depolama, hafıza?
Supercell

SSL, mobil uygulamayı değil, yalnızca Mobil cihazı onaylar.
Morons

@Supercell: Ben bir cevap ekleyeceğiz
ATK

Yanıtlar:


48

Yapamazsın.

Bir kişiyi, donanım istemcisini veya yazılım istemcisini , herhangi bir varlığı asla doğrulayamazsınız . Yalnızca söylediklerinin doğru olduğunu doğrulayabilir , sonra dürüstlüğü üstlenebilirsin .

Örneğin, Google, Gmail hesabıma giriş yaptığımı nasıl biliyor ? Onlar sadece bir kullanıcı adı ve parola bana sor, doğrulamak o , o zaman dürüstlük varsayalım başka kim bilgi var çünkü? Bir noktada, Google bunun yeterli olmadığına karar verdi ve davranış doğrulaması ekledi (garip davranışlar arıyor) ama bu davranışını yapmak için hala insana güveniyor ve ardından davranışı doğruladı .

Bu tam olarak Müşteriyi doğrulamakla aynı şeydir. Yalnızca Müşterinin davranışını doğrulayabilirsiniz , ancak Müşterinin kendisini doğrulayamazsınız .

Böylece, SSL ile Müşterinin geçerli bir sertifikası olup olmadığını kontrol edebilirsiniz, Böylece bir kişi Uygulamanızı kurabilir, Sertifikayı alabilir ve tüm yeni kodları çalıştırabilir.

Öyleyse soru şudur: Bu neden bu kadar kritik? Bu gerçek bir endişe ise, şişman bir müşteri seçiminizi sorgularım. Belki bir web uygulaması ile gitmelisin (bu yüzden API'nizi ifşa etmeniz gerekmez).

Ayrıca bakınız: Android Uygulamaları için SSL Sertifikası Doğrulamasını Yenme

ve: Bir mobil uygulamadaki istemci SSL sertifikaları ne kadar güvenli?


1
İstemci sertifikalarını, sertifikanın işletim sistemi tarafından şifrelenmiş bir sürücüde depolandığı donanımda kullandım. Fakat orada bile, kimse kusursuz olduğunu düşünmüyordu. Amaç sadece sıradan kullanıcılar için zorlaştırmaktı.
Steven Burnap

1
@Morons: Bir webapp bunu çözecektir, ancak kullanıcıların yerel uygulamayı bir webapp'tan daha kullanma ihtimalinin yüksek olacağını düşünüyoruz (varsayımımız yanlışsa lütfen beni düzeltin). Bunun bu kadar kritik olmasının nedeni, API'nin kullanıcılara, aylarca çalışarak topladığımız birçok veriyi içeren veritabanımızın bölümlerine erişim izni vermesidir. Diğer şirketlerin veya kullanıcıların kolayca kendi amaçları için kullanabilecekleri verilerdir. Müşterileri güvenceye almazsak, kimin kullandığını bilmiyoruz (bize karşı).
Supercell

6
Bir webapp sorunu çözmez. Herhangi bir webapp istemci tarafında değiştirmek ve ne istersen onu yapmak oldukça önemsizdir.
Steven Burnap

5
@Supercell Birine veri gösteremez ve sonra paylaşmalarını durduramazsınız. Bazılarının Data'ya sahip olmasını istemiyorsanız, onlara göstermeyin (gösterin).
Morons

Kabul ediyorum ama farklı sebeplerden dolayı. Cihazlar üzerinde kontrol sahibi olsaydın, rsa en.wikipedia.org/wiki/SecurID gibidir . Ancak cep telefonları kontrol edilebilecek bir şey değildir (bir eklenti anahtarı gibi ekleri kabul edebilirler).
imel96

31

Kullanıcı girişleri ve SSL üzerinden iletişim ile başa çıkmakta rahat olduğunuzdan eminim, bu yüzden sorunun daha ilginç bir parçası olduğunu düşündüğüm şeye odaklanacağım: salt okunur hareketlerinizin nasıl sağlanacağını - hangi do not gerektiren kullanıcı kimliğinin doğrulanması - sadece kendi istemci uygulamalarından kabul edilmektedir?

Her şeyden önce, fNek'in daha önceki bir cevabında ima ettiği dezavantajı var - müşteri uygulamalarınız potansiyel olarak düşmanca kullanıcıların elinde. İncelenebilir, iletişimleri denetlenebilir, kodları demonte edilebilir. Önereceğim hiçbir şey , birisinin müşterinizi tersine çevirmeyeceğini ve REST API'nizi kötüye kullanmayacağını garanti etmenize izin vermez. Ancak herhangi bir geçici girişimin önüne bir engel koymalıdır.

Neyse, ortak bir yaklaşım:

  • Müşteri bir sır içeriyor
  • Bir istek yaparken, istek parametrelerini sırlarla birleştirir ve sonucu özetler
  • Bu karma istek ile birlikte gönderilir ve sunucu tarafından kontrol edilir

örneğin, bir GETistek düşünün/products/widgets

Müşteri sırrının "OH_HAI_I_IZ_SECRET" olduğunu varsayalım

HTTP fiili ile URL ve sırrı birleştirin:

GET/products/widgetsOH_HAI_I_IZ_SECRET

Ve buna bir SHA-1 karması alın:

4156023ce06aff06777bef3ecaf6d7fdb6ca4e02

Öyleyse bunu yollayın, böylece istek şöyle olacaktır:

GET /products/widgets?hash=4156023ce06aff06777bef3ecaf6d7fdb6ca4e02

Son olarak, birinin en azından bireysel istekleri tekrar etmesini önlemek için ayrıca bir zaman damgası alın ve bunu parametrelere ve hash'a ekleyin. Örneğin, şu an Unix zamanında 1384987891'dir. Bunu birleştirme işlemine ekleyin:

GET/products/widgetsOH_HAI_I_IZ_SECRET1384987891

Hash o:

2774561d4e9eb37994d6d71e4f396b85af6cacd1

Ve gönder:

GET /products/widgets?time=1384987891&hash=2774561d4e9eb37994d6d71e4f396b85af6cacd1

Sunucu, hash değerini kontrol eder ve zaman damgasının güncel olduğunu doğrular (örneğin, saatlerin mükemmel şekilde senkronize edilmemesi için 5 dakika içinde)

Uyarı! Mobil uygulamalardan bahsettiğinizden beri, birinin telefonunun saati yanlış olması kesin bir risk. Ya da saat dilimi yanlış. Ya da başka birşey. Karışıma zaman eklemek muhtemelen bazı yasal kullanıcıları kırar, bu yüzden bu fikri dikkatli kullanın.


6
Bu karma mekanizma, apk bir araya getirdiğinde herhangi bir programcı tarafından anlaşılabilir.
Punith Raj,

8
@PunithRaj tam olarak, ikinci paragrafta bunu ele aldım. “Önereceğim hiçbir şey, birisinin müşterinizi tersine mühendislik yapmamasını ve REST API'nizi kötüye kullanmamasını garanti etmenize izin vermez.
Carson63000 0

Uyarı için sunucuda ve mobil cihazda UTC kullanıyorum, bu sorunu çözdü değil mi?
shareef

@ Carson63000 - Peki, somut bir çözüm var mı? Herkese açık olması gereken (web'de veya bir mobil uygulamada oturum açmadan önce bir kullanıcının kayıt olması gerekir) ve binlerce sahte kullanıcı oluşturmak için botlar tarafından hedeflenebilir.
Tohid

17

İlgilenen herkese, Android'de almış olduğunuz isteğin uygulamanızdan gönderildiğini doğrulayabilirsiniz.

Kısacası, uygulamanızı google'a yüklediğinizde, yalnızca sizin (ve google'ın) bildiği benzersiz bir anahtarla imzalarsınız.

Doğrulama işlemi şöyle devam eder (ish):

  1. uygulamanız google’a gidiyor ve auth token isteyin
  2. Uygulamanız, simgeyi güvenli bir şekilde arka tarafınıza gönderir.
    1. arka ucunuz google’a gidiyor ve uygulamanızdan aldığı kimlik kartını kontrol ediyor.
    2. Ardından, arka ucunuz, uygulamanızın imzaladığı benzersiz anahtarın uyuşup uyuşmadığını kontrol eder;

açıklayan tam blog ve nasıl uygulanacağı burada bulunabilir: http://android-developers.blogspot.co.il/2013/01/verifying-back-end-calls-from-android.html


1
İyi cevap, ancak kötü niyetli bir kullanıcı hala yeterli çabayla bir uygulamayı taklit edebilir. fakat hiçbir şey gerçekten güvenli değildir, mesele ne olursa olsun, mesele sadece
mateos

1
İOS için bu seçenek vardır: link DeviceCheck API'leri, aldığınız belirtecin, uygulamanızın indirildiği gerçek bir Apple cihazından geldiğini doğrulamanıza izin verir
Iwaz

Hesap gerektirir (e-postalar)
user25

5

Tamam, başlamadan önce bahsetmeye değer, çoğu uygulama için bu oldukça fazla müstehcendir. Çoğu kullanım durumunda, sadece tek bir geçerli sertifikaya ve / veya jetona sahip olmak fazlasıyla yeterlidir. Uygulamanızın kodunu açmak gibi sert bir şey yapmayı içeriyorsa, çok değerli veriler sağlamadığınız sürece çoğu bilgisayar korsanı bile rahatsız olmaz. Ama hey, bu cevabın eğlencesi nerede?

Yani yapabilecekleriniz, programları imzalamak için kullanılan dijital imzaya benzeyen asimetrik şifreleme oluşturmaktır. Her uygulama, tek bir CA tarafından verilen ve kullanıcı bağlandığında doğrulanan ayrı bir sertifikaya sahip olabilir. (ilk kayıt olurken veya ilk kurulum sırasında) Bu sertifikanın kimliği doğrulandığında, o sertifikayı, verilen bir cihaz tanımlayıcısı için geçerli bir şekilde ( Android ID gibi ) kaydederek başvurunuzu daha da güvenli hale getirebilirsiniz.


5

@Morons'un cevabında bahsettiği gibi, bağlantının diğer ucundaki varlığı doğrulamak çok zor.

Bir otantiklik düzeyi sağlamanın en basit yolu, sunucunun yalnızca gerçek varlığın bileceği bir sırrı kontrol etmesini sağlamaktır. Bir kullanıcı için bu bir kullanıcı adı ve şifre olabilir. Kullanıcının bulunmadığı bir yazılım için bir sır verebilirsiniz.

Bu yaklaşımların sorunu müşteriye biraz güvenmek zorunda olmanızdır. Birisi uygulamanızı tersine çevirirse veya şifrenizi çalarsa, sizin gibi davranabilirler.

Gizli bilgiyi çalıştırılabilir dosyada gizleyerek zorlaştırmayı zorlaştırmak için adımlar atabilirsiniz. Java için bir obfuscator olan ProGuard gibi araçlar, bu konuda yardımcı olabilir, diğer dillerde şaşırtmaca hakkında pek bir şey bilmiyorum ama muhtemelen benzer araçlar var. Bir TLS bağlantısı kullanmak, insanların trafiğinizde gizlenmelerini önlemeye yardımcı olur, ancak bir MITM saldırısını engellemez. Sabitleme , bu sorunu gidermeye yardımcı olabilir.

CriticalBlue (Tam açıklama!) Adlı ve bu güven sorununu gidermeye çalışan bir ürünü olan bir şirket için çalışıyorum. Şu anda Android / iOS için çalışıyor ve sunucularımızın istemci uygulamasının bütünlüğünü kontrol etmesi için bir mekanizma sağlıyor. Bunu müşteriye rastgele bir mücadeleye cevap hesaplamasını sağlayarak yapar. Müşteri, takılan uygulama paketinin sahte olması zor olan ve bazı gelişmiş kurcalamaya karşı koruma mekanizmaları içeren niteliklerini kullanarak yanıtı hesaplamalıdır.

Daha sonra API'nıza orijinallik kanıtı olarak gönderebileceğiniz bir belirteç döndürür.

Bu yaklaşımla ilgili önemli fark, istemcideki orijinallik kontrolünü devre dışı bırakmak mümkün olsa da, bunu yaptıysanız, uygulamanızı sunucu ile doğrulamanız için gereken doğrulama kodunu alamazsınız. Kütüphane aynı zamanda içinde bulunduğu çalıştırılabilirliğin özelliklerine sıkı sıkıya bağlıdır, bu yüzden sahte bir uygulamaya gömmek ve çalışmasını sağlamak çok zor olacaktır.

Herhangi bir API geliştiricisinin, birinin API'sini hacklemeye çalışmasının ne kadar muhtemel olduğuna ve bunun ne kadar maliyetli olacağına karar vermesi için yapması gereken bir maliyet / fayda analizi vardır. Uygulamadaki basit bir gizli kontrol önemsiz saldırıları önler, ancak kendinizi daha kararlı bir saldırgana karşı korumak muhtemelen daha karmaşık ve potansiyel olarak maliyetlidir.


0

SSL iletişim kanalını güvence altına alır.

Başarılı bir oturum açma, şifreli bağlantı üzerinden bir kimlik doğrulama kodu verir.

Kimlik doğrulama belirteci, sonraki tüm isteklerde REST API'nize aktarılır.


1
Bazı ek bilgiler ekledim. Belirttiğiniz gibi, bir erişim belirteciyle kimlik doğrulama yapmayı planlıyordum. REST API, kullanıcının yalnızca belirli eylemler için oturum açmasını gerektirmez. Her iki durumda da müşterilerin imzalanması / güvenilmesi gerekir.
Supercell

Yerel mobil geliştirme hakkında pek bir şey bilmiyorum, ancak mobil uygulamanız REST API’ye cep telefonu numarasını verebilir mi? Android telefonuma uygulamaları yüklediğimde, sık sık uygulamaya belirli izinler vermem isteniyor. Güvenli bağlantı üzerinden her isteği içeren bir cep telefonu numarası gönderebilirseniz, tüm istekleri bilinmeyen cep telefonu numarasıyla reddedebilirsiniz. Sadece burada yüksek sesle düşünüyorum ...
CodeART 20:13

Bu işe yarayabilir, ancak kullanıcının oturum açmasını ve kullanıcı hesabına bağlı numarayı gerektirmesi gerekir. Aksi halde, sunucuya karşı numarayı doğrulayacak bir şey olmazdı.
Supercell

Mobil uygulamanızı nasıl yükleyeceksiniz?
CodeART

Onlar app store (Google, Apple, Microsoft) aracılığıyla satışa sunulacak
Supercell

0

Çok güvenli olmazdı, ancak bir tür gizli kod veya hatta dijital bir imza ekleyebilirsiniz. Dezavantajı: Ne yaptığınızı biliyorsanız, edinmenizi kolaylaştıran uygulamaya dahil edilmelidir.


0

Bildiğim kadarıyla, HTTPS sadece iletişim kurduğunuz sunucuyu doğrulamak için kim olduğunu söylüyor.

Aslında, hem istemciyi hem de sunucuyu doğrulamak için SSL kullanabilirsiniz. Veya farklı bir şekilde belirtildiği gibi "evet, müşteri sertifikalarını kullanabilirsiniz".

İhtiyacın olacak ...

  • mobil cihazda istemci sertifikalarının nasıl belirleneceğini belirlemek için kullandığınız SSL kütüphanesine bakın,
  • Kod yaz veya HTTPS sunucunuzu yalnızca güvenilir, kayıtlı istemcilerden gelen bağlantıları kabul edecek şekilde yapılandırın.
  • Sunucunuza güvenilir istemci sertifikaları eklemek için bir mekanizma ile gelip
  • artık güvenilmeyen istemci sertifikalarını sunucunuzdan kaldırma mekanizması

Mobil uygulamanın sertifikayı istediğiniz yerde saklamasını sağlayabilirsiniz. Uygulamaya özel kimlik doğrulamasını istediğinizden, sertifikayı korumalı bir disk konumunda saklamayı düşünmelisiniz (Android'de, SQLite veritabanınızda bir "config" tablosu, sertifikanız için bir satır ve özel anahtarınız için bir satır oluşturabilirsiniz) .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.