Neden bir API anahtarı ve sırrı kullanmalı?


93

Kullanıcıya hem bir API anahtarı hem de bir sır veren birçok API ile karşılaştım . Ama sorum şu: ikisi arasındaki fark nedir?

Benim gözümde bir anahtar yeterli olabilir. Diyelim ki bir anahtarım var ve bunu sadece ben ve sunucu biliyor. Bu anahtarla bir HMAC hash oluşturup bir API çağrısı yapıyorum. Sunucuda, HMAC hash'ini tekrar oluşturup gönderilen hash ile karşılaştırıyoruz. Aynıysa, arama doğrulanır.

Öyleyse neden iki anahtar kullanıyorsunuz?

Düzenleme: veya bu API anahtarı API sırrını aramak için mi kullanılıyor?


Yanıtlar:


47

Gizli anahtar şifreleme, bir mesajı kodlamak ve daha sonra çözmek için aynı anahtarı kullanmaya dayanır. Böylece mesajı yalnızca "sırrı" bilenler okuyabilir.

RSA güvenliği 2 eşleşen anahtara dayanır. Her kullanıcı için bir genel anahtar vardır ve herkes bunu bilebilir (olmalıdır). Ayrıca sadece kullanıcının bilmesi gereken özel bir anahtar vardır. Genel anahtarla şifrelenen bir mesajın şifresi yalnızca özel anahtarla çözülebilir ve bunun tersi de geçerlidir.

Bu nedenle, size yalnızca sizin okuyabileceğiniz bir mesaj göndermek istersem, (ağdan) genel anahtarınızı alırım, mesajı bu anahtarla şifrelerim ve şifresini çözebilecek tek kişi sizsiniz.

Ya da size bir mesaj gönderdiğimi kanıtlamak istersem, mesajı özel anahtarımla şifreleyebilir, size (açık metinde veya başka bir mesajda) nasıl şifrelendiğini söyleyebilirim. Sonra benim açık anahtarımla mesajın şifresini çözebilirsiniz ve eğer okunabilir hale gelirse, benden geldiğini anlarsınız.

Bu şifreleme biçimi oldukça bilgisayar yoğun bir işlemdir, bu nedenle bazen yapılan şey, RSA teknolojisi ile bir kerelik "gizli anahtarı" şifrelemek, ardından mesajın geri kalanını gizli anahtarla şifrelemek ve ardından imzamı ikinci şekilde şifrelemektir. Daha sonra bu işlemi tersine çevirirsiniz, böylece mesaj ve imza okunabilirse, siz ve yalnızca siz okuyabilirsiniz ve mesajı benim gönderdiğimden emin olabilirsiniz.

VEYA

daha detaylı açıklama için bu bağlantıyı ziyaret edebilirsiniz.

API Anahtarları ve Gizli Anahtarlar nasıl çalışır?


9
Güzel cevap, ancak API sırlarını ve anahtarlarını Facebook veya Gmail vb. İle kullandığımda, hiçbir noktada hiçbir şeyi şifrelemem veya hash etmemem gerekmiyor. Bu durumlarda, API sırlarının ve anahtarlarının amacı nedir?
Quintonn

2
Facebook'u örnek olarak kullandığınızda app_secret kullanacağınız iki senaryo vardır. İlki, hashing gerektirmez. Öncelikle yönlendirme URL'nizin ele geçirilmesini önlemek için kullanılır. Bir kullanıcı oturum açtıktan ve uygulamanıza erişim izni verdikten sonra, facebook erişim jetonunu doğrudan yönlendirme url'sine gönderdiyse, erişim jetonunun Facebook'tan olup olmadığını doğrulamanın hiçbir yolu olmazdı. Yönlendirme url'nize kendi erişim jetonumu gönderebilir ve API'nizden gelecek facebook işlemlerini gerçekleştirebilirim. Bunun yerine facebook, yönlendirme url'sine bir kod gönderir. API daha sonra kodu gerçek erişim belirteci ile değiştirir.
Ryan Thomas

2
İkinci kısımda, kodu gerçek erişim belirteci ile değiştiren facebook, api'nizin kimliğini bir imza ile doğrulamasını bekler. Bu senaryoda, imzalamak için açık anahtar şifrelemesine ihtiyaç duymazlar, yalnızca uygulamanızı gerçekten gizli tutmanız ve imzanız olarak kullanmanız için size güvenirler. Bu bana her zaman aptalca geldi ve bir imza oluşturmak için tek yönlü bir işlev kullanmamak, ancak uygulama sırrının doğrudan kullanımına karar vermek için performans gibi nedenlere sahip olduklarını düşünüyorum.
Ryan Thomas

İkinci kullanım durumunda kriptografik karma kullanırsınız. Facebook ile etkileşim kurmaya başlamak için gerçek access_token'a sahip olduktan sonra, uygulamanızın kimliğine bürünmesini önlemek için ekstra güvenlik isteyebilirsiniz. Facebook uygulama konsolunda, uygulamanızdan gelen her facebook api isteğinin, erişim belirtecine ek olarak imzanızı içermesini gerektiren bir özelliği etkinleştirebilirsiniz. Sadece nedenlerini tahmin ediyorum ama bu noktada sanırım her istekle imza olarak app_secret'i tekrar tekrar göndermenizi istemiyorlar. Ne kadar çok gönderirseniz, app_secret'in tehlikeye atılma şansı o kadar artar.
Ryan Thomas

1
Sanırım bu ekstra güvenlik özelliğini etkinleştirdiğiniz için, Facebook'un imzanızı kriptografik bir hash çağrısı ile doğrulayan ekstra performans ek yüküne izin vermek için bir çeşit karar vermişsinizdir. Her neyse, bu senaryoda Facebook api isteklerinizle iki değer iletirsiniz. Access_token ve imzanız olarak hizmet veren appsecret_proof adlı bir değer. Uygulama gizli kanıtı, anahtar olarak app_secret kullanılarak access_token'ın kriptografik karması ile oluşturulur.
Ryan Thomas

55

İki ayrı anahtara ihtiyacınız var, biri onlara kim olduğunuzu söyleyen, diğeri de söylediğiniz kişi olduğunuzu kanıtlayan .

"Anahtar" kullanıcı kimliğinizdir ve "gizli" şifrenizdir. Sadece "anahtar" ve "gizli" terimlerini kullanıyorlar çünkü bunu böyle uyguladılar.


1
Peki ya https üzerinden iletişim kuruyorsanız? O halde mesajınızı gizli bir anahtarla şifrelemenin ne anlamı var?
kamuniaft

6
Önemli olan her zaman riski azaltmaktır. Https iletişimi tehlikeye atılırsa, isteğinizi okuyabilen bir saldırgan yenilerini taklit edemez.
API'niz

Sanırım amacının iki ayrı anahtar olması, tek bir istemci uygulamasının farklı kullanıcılarının farklı sırlara sahip olabilmeleridir, aksi takdirde hepsi aynı sırra sahip olsaydı, bir anahtara sahip olmak işe yaramaz. Sağ?
Honey

Bu API neden bunun için Bearer:kimlik doğrulama kullanmıyor ? Orada bir kimliğiniz ve bir şifreniz olacaktır.
Stefan Haberl

7

Basit cevap, eğer doğru anladıysam ...

API anahtarınızı şifreleme için kullanırsanız, hizmet kiminle iletişime geçtiğini nasıl bilecek? Bu mesajın şifresini nasıl çözecekler?

Kim olduğunuzu belirtmek için API anahtarını kullanırsınız, bu, düz metin olarak gönderdiğiniz şeydir. Kimseye göndermediğiniz GİZLİ anahtar . Sadece şifreleme için kullanırsınız. Sonra şifreli mesajı gönderirsiniz. Amacı bozacak şifreleme için kullanılan anahtarı göndermezsiniz.


Siz yapıyorsunuz. API anahtarını sunucuya gönderirsiniz. Yani bu, sunucuyla iletişiminizi kesen herhangi birine bu değeri verdiğiniz anlamına gelir.
ancajic

Neredeyse gördüğüm her API, sunucuya hem anahtarı hem de sırrı gönderiyorsunuz. Sunucuya bağlantı teorik olarak aynı güvenlik seviyesi ile şifrelenmiştir. Ama sunucudan başka kimseye asla vermem.
sudo

secretDüz metin gönderirken hiç görmedim . Bana bir bağlantı verebilir misin secretBazı verileri şifrelemek için kullandığımı gördüm . Ve şifrelenmiş verilerle birlikte apiKey, sunucunun verilerin şifresini nasıl çözeceğini bilmesi için gönderme .
ancajic

twilio.com/docs/sms/tutorials/… ve nexmo.github.io/Quickstarts/sms/send , StackOverflow'da arama yapmamı sağlayan gördüğüm örneklerdir.
sudo

Twilio bu terimleri tam olarak kullanmıyor. Ama Nexmo emin onlar sadece veri aradığınız gibi bir bakışta sonra, öyle görünüyor ki, ... Ama secretve apiKeyve ne onlar aslında yapıyor usernameve password. Bu tamamen farklı bir şey ...
ancajic

3

Sır ve (genel) anahtarın ne olduğunu açıklayan cevaplar var. Kafa karıştırıcı isimler verdikleri genel-özel bir anahtar çifti. Ancak API'lerin neden her ikisini de gerektirdiğini kimse söylemiyor ve birçok API size yalnızca bir sır veriyor! Ayrıca, neden iki anahtarları olduğunu açıklayan herhangi bir API dokümanı görmedim, bu yüzden yapabileceğim en iyi şey spekülasyon yapmak ...

En iyisi, isteğinize yalnızca genel anahtarınızı eklemek ve isteği yerel olarak özel anahtarınızla imzalamaktır; daha fazlasını göndermeye gerek olmamalı. Ama bazıları sırrın sırrını istediği için sıyrılıyor. Tamam, herhangi bir iyi API, TLS gibi (genellikle HTTPS üzerinden) bir miktar taşıma güvenliği kullanır. Ancak yine de özel anahtarınızı sunucuya bu şekilde açığa çıkarıyorsunuz ve bir şekilde onu yanlış kullanma riskini artırıyorsunuz (bkz: GitHub ve Twitter'ın şifre günlüğü hatası yakın zamanda keşfedildi). Ve HTTPS teorik olarak aynı derecede güvenlidir, ancak orada her zaman uygulama kusurları vardır.

Ancak çoğu - aslında çoğu göründüğü gibi - API'ler her iki anahtarı da isteklerde göndermenizi sağlar çünkü bu, insanlara kendi imzalarını yaptırmaktan daha kolaydır; aksi takdirde saf cURL örnekleri olamaz! Bu durumda, onları ayırmak anlamsız. Sanırım ayrı anahtarlar, daha sonra onlardan yararlanmak için API'yi değiştirmeleri durumunda. Veya bazılarının bunu daha güvenli bir şekilde yapabilecek bir istemci kitaplığı vardır.


1

O Marcus Adams'ın cevabın bir uzantısıdır rağmen, burada bahsedilen görmedim o bir şey, bir ihtimal varsa belirlemek ve bir kullanıcının kimliğini doğrulamak hem tek bir bilgi parçası kullanarak olmamalıdır ki zamanlama saldırıları , hangi olabilir Bir dizi karşılaştırmasının ne kadar ileri gittiğini tahmin etmek için yanıt sürelerindeki farklılıkları kullanın.

Kullanıcıyı veya kimlik bilgilerini aramak için "anahtar" kullanan bir sistem kullanıyorsanız, bu bilgi parçası, binlerce istek göndererek ve veritabanınızın bulması (veya bulmaması) için geçen süreyi inceleyerek zaman içinde aşamalı olarak tahmin edilebilir. bir kayıt bulun. Bu, özellikle "anahtar" anahtarın tek yönlü karması yerine düz metin olarak saklanıyorsa geçerlidir. Anahtarı kullanıcıya tekrar görüntüleyebilmeniz gerekirse, kullanıcıların anahtarlarını düz metin olarak veya simetrik olarak şifrelenmiş olarak saklamak isteyebilirsiniz.

İkinci bir bilgi parçasına veya "sırrına" sahip olarak, önce bir zamanlama saldırısına karşı savunmasız olabilecek "anahtar" ı kullanarak kullanıcıyı veya kimlik bilgilerini arayabilir, ardından değerini kontrol etmek için zamanlama açısından güvenli bir karşılaştırma işlevi kullanabilirsiniz. sır".

İşte Python'un bu işlevi uygulaması:

https://github.com/python/cpython/blob/cd8295ff758891f21084a6a5ad3403d35dda38f7/Modules/_operator.c#L727

Ve hmackitaplıkta (ve muhtemelen diğerlerinde) açığa çıkar :

https://docs.python.org/3/library/hmac.html#hmac.compare_digest


Burada dikkat edilmesi gereken bir nokta, bu tür bir saldırının aramadan önce karma hale getirilmiş veya şifrelenmiş değerler üzerinde çalışacağını düşünmediğimdir, çünkü karşılaştırılan değerler, giriş dizesindeki bir karakter her değiştiğinde rastgele değişir. Bunun iyi bir açıklamasını burada buldum .

API anahtarlarını depolamak için çözümler şu şekilde olacaktır:

  1. Ayrı bir anahtar ve sır kullanın, kayda bakmak için anahtarı kullanın ve sırrı kontrol etmek için zamanlama açısından güvenli bir karşılaştırma kullanın. Bu, kullanıcıya anahtarı ve sırrı bir kullanıcıya tekrar göstermenizi sağlar.
  2. Ayrı bir anahtar ve sır kullanın, sır üzerinde simetrik, belirleyici şifreleme kullanın ve şifrelenmiş sırlar arasında normal bir karşılaştırma yapın. Bu, kullanıcıya anahtarı ve sırrı tekrar göstermenize olanak tanır ve sizi zamanlama açısından güvenli bir karşılaştırma yapma zorunluluğundan kurtarabilir.
  3. Ayrı bir anahtar ve sır kullanın, sırrı görüntüleyin, karma oluşturun ve saklayın, ardından karma sırrın normal bir karşılaştırmasını yapın. Bu, iki yönlü şifreleme kullanma zorunluluğunu ortadan kaldırır ve sistem tehlikeye girerse sırrınızı güvende tutma avantajına sahiptir. Sırrı kullanıcıya tekrar gösterememenin dezavantajı var.
  4. Tek bir anahtar kullanın , kullanıcıya bir kez gösterin, hashing uygulayın, ardından karma veya şifreli anahtar için normal bir arama yapın. Bu tek bir anahtar kullanır, ancak kullanıcıya tekrar gösterilemez. Sistem tehlikeye atılırsa anahtarları güvende tutma avantajına sahiptir.
  5. Tek bir anahtar kullanın , kullanıcıya bir kez gösterin, şifreleyin ve şifrelenmiş sırrı normal bir şekilde arayın. Kullanıcıya tekrar gösterilebilir, ancak sistemin güvenliği aşılırsa anahtarların savunmasız kalması pahasına.

Bunlardan 3'ün en iyi güvenlik ve rahatlık dengesi olduğunu düşünüyorum. Anahtarlar verilirken bunun birçok web sitesinde uygulandığını gördüm.

Ayrıca, gerçek güvenlik uzmanlarını bu yanıtı eleştirmeye davet ediyorum. Bunu başka bir tartışma noktası olarak ortaya çıkarmak istedim.

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.