Yeni bir API anahtarı oluşturmak için en iyi yaklaşım nedir?


92

Yani şu anda birçok farklı hizmetle, Google API'leri, Twitter API'leri, Facebook API'leri vb.

Her hizmetin aşağıdakiler gibi bir API anahtarı vardır:

AIzaSyClzfrOzB818x55FASHvX4JuGQciR9lv7q

Tüm anahtarların uzunlukları ve içerdikleri karakterler değişir, bir API anahtarı oluşturmak için en iyi yaklaşımın ne olduğunu merak ediyorum.

Kullanıcı uygulamasının ayrıntılarının şifrelenmesi mi, yoksa bir karma mı, yoksa rastgele bir dizenin karması mı, vb. Olsun, belirli bir dil istemiyorum, yalnızca anahtar oluşturmaya yönelik genel yaklaşım. Karma algoritma hakkında endişelenmeli miyiz? (MSD, SHA1, bcrypt) vb.

Düzenleme: Birkaç arkadaşımla konuştum (e-posta / twitter) ve sadece kısa çizgilerle bir GUID kullanılmasını önerdiler.

Biraz daha fikir edinmeyi umduğum için bu bana biraz karışık geliyor.


Yanıtlar:


59

Kriptografi için tasarlanmış rastgele bir sayı üreteci kullanın. Sonra base-64 sayıyı kodlar.

Bu bir C # örneğidir:

var key = new byte[32];
using (var generator = RandomNumberGenerator.Create())
    generator.GetBytes(key);
string apiKey = Convert.ToBase64String(key);

2
Bu çok güvenli değil, veritabanınıza erişim sağlayan bir saldırgan anahtarı alabilir. Anahtarı, bir sunucu sırrı ile birlikte, kullanıcıya özgü (bir tuz gibi) bir şeyin karması olarak oluşturmak daha iyi olacaktır.
James Wierzba

14
Rastgele oluşturulmuş bir API anahtarının saklanması, karma bir parolanın depolanmasıyla aynı güvenlik özelliklerine sahiptir. Çoğu durumda sorun değil. Önerdiğiniz gibi, rastgele üretilen sayının bir tuz olduğunu düşünmek ve ona bir sunucu sırrı ile hashing uygulamak mümkündür; ancak, bunu yaparak, her doğrulamada karma ek yüke maruz kalırsınız. Ayrıca, tüm API anahtarlarını geçersiz kılmadan sunucu sırrını geçersiz kılmanın bir yolu yoktur.
Edward Brey

Güzel çözüm, ancak apiKey'den önce var anahtar kelimesine ihtiyacınız var :) var apiKey = Convert.ToBase64String (key);
Dawid Ohia

@ JohnM2 Sağ. apiKeyBaşka bir yerde ilan edilebileceğinden , ucu açık bırakıyordum . Açıklık için türü ekledim.
Edward Brey 18

4
@JamesWierzba, eğer saldırıya uğrayan zaten veritabanınızdaysa, API'nize güvenli olmayan erişime sahip olmaları muhtemelen endişelerinizin en küçüğüdür ...
Jon Story

30

API anahtarlarının şu özelliklere sahip olması gerekir:

  • Yetkili bir API kullanıcısını benzersiz şekilde tanımlama - "API anahtarı" nın "anahtar" kısmı
  • o kullanıcının kimliğini doğrulayın - tahmin edilemez / sahte olamaz
  • Bir kullanıcı hatalı davranırsa iptal edilebilir - tipik olarak bir kaydı silebilecek bir veritabanına girerler.

Tipik olarak milyarlarca değil, binlerce veya milyonlarca API anahtarına sahip olursunuz, bu nedenle aşağıdakileri yapmaları gerekmez:

  • API kullanıcısı hakkındaki bilgileri güvenilir bir şekilde depolayın çünkü bunlar veritabanınızda saklanabilir.

Bu nedenle, bir API anahtarı oluşturmanın bir yolu, iki parça bilgi almaktır:

  1. benzersizliği garanti eden bir seri numarası
  2. anahtarı doldurmak için yeterince rastgele bit

ve özel bir sır kullanarak imzalayın.

Sayaç, kullanıcıyı benzersiz bir şekilde tanımlamalarını garanti eder ve imzalama sahteciliği önler. İptal edilebilirlik, API anahtarı yetkilendirmesi gerektiren herhangi bir şey yapmadan önce anahtarın veritabanında hala geçerli olup olmadığını kontrol etmeyi gerektirir.

İyi bir GUID üreteci, birden çok veri merkezinden anahtarlar oluşturmanız gerekiyorsa veya seri numaralarını atamak için iyi bir dağıtılmış yolunuz yoksa, artırılmış bir sayacın oldukça iyi bir yaklaşımıdır.


veya rastgele bir dizenin karması

Hashing sahteciliği engellemez. İmzalamak , anahtarın sizden geldiğini garanti eden şeydir.


3
Bir istemci tarafından sunulan API anahtarı, API'yi sağlayan sunucuda önceden kayıtlı API anahtarlarının bulunduğu bir veritabanına karşı kontrol edilirse, algoritmanızın imzalama adımı gerekli midir? Anahtarları sağlayan sunucu sunucu ise, burada imzalama gereksiz gibi görünüyor.
sappenin

3
@sappenin, Evet. Sunucuda tanımlanamayan bir anahtar saklarsanız, sahteciliği önlemeniz gerekmez. Genellikle API isteği makinelerin bir çiftlikte herhangi biri tarafından ele alınır - Sunucu birçok sunuculardan biridir. İmza kontrolü, bazı durumlarda yarış koşullarından kaçınabilen bir veritabanına gidiş dönüş olmaksızın herhangi bir makinede yapılabilir.
Mike Samuel

1
@MikeSamuel API anahtarı imzalanmışsa ve Veritabanına gidiş-dönüş yapmazsanız, anahtar iptal edildiğinde ancak yine de API'ye erişmek için kullanıldığında ne olur?
Abhyudit Jain

@AbhyuditJain, Herhangi bir dağıtılmış sistemde tutarlı bir mesaj sırasına (iptaller - iptal edilen kimlik bilgilerinin sonraki kullanımlarından önce gerçekleşir ) veya belirsizliği sınırlandırmak için başka yollara ihtiyacınız vardır. Bazı sistemler her istekte geri dönüş yapmaz - bir düğüm, bir anahtarın veritabanında 10 dakika olduğu gerçeğini önbelleğe alırsa, yalnızca 10 dakika vardır. bir saldırganın iptal edilmiş bir kimlik bilgilerini kötüye kullanabileceği pencere. Yine de olası bir kafa karışıklığı ortaya çıkabilir: kullanıcı bir kimlik bilgisini iptal eder, ardından iptal edildiğini test eder ve şaşırır çünkü yapışkan olmayan oturumlar iki isteğin farklı düğümlere gitmesine neden olur.
Mike Samuel

5

Tire olmadan küçük harflerle biçimlendirilmiş UUID'leri kullanıyorum.

Oluşturmak kolaydır, çünkü çoğu dilde yerleşik olarak bulunur.

API anahtarlarının güvenliği ihlal edilebilir, bu durumda bir kullanıcı API anahtarını iptal etmek ve yeni bir tane oluşturmak isteyebilir, bu nedenle anahtar oluşturma yönteminizin bu gereksinimi karşılayabilmesi gerekir.


15
UUID'lerin tahmin edilmesinin zor olduğunu varsaymayın; güvenlik yetenekleri olarak kullanılmamalıdır (UUID spesifikasyonu RFC4122 bölüm 6 ). Bir API anahtarının güvenli bir rasgele sayıya ihtiyacı vardır, ancak UUID'ler güvenli bir şekilde tahmin edilemez değildir .
Edward Brey

3
@EdwardBrey Java'da ne dersiniz UUID uuid = UUID.randomUUID();? Rastlantının yeterince iyi olmadığını mı söylüyorsun?
Mikro

8
@MicroR Rastgele bir UUID, yalnızca onu yapmak için kullanılan rastgele sayı üreteci şifreleme açısından güvenli ve 128 bit yeterliyse güvenlidir. UUID RFC güvenli bir rasgele sayı üreteci gerektirmese de, belirli bir uygulama birini kullanmakta serbesttir. RandomUUID durumunda , API belgeleri özellikle "şifreleme açısından güçlü sözde rasgele sayı üreteci" kullandığını belirtir. Bu nedenle, belirli bir uygulama 128 bit API anahtarı için güvenlidir.
Edward Brey

4

Yalnızca alfasayısal karakterler içeren bir API anahtarı istiyorsanız, base64-random'un bir varyantını kullanabilirsiniz. bunun yerine yalnızca base-62 kodlaması kullanarak yaklaşımının . Baz-62 kodlayıcı dayanmaktadır bu .

public static string CreateApiKey()
{
    var bytes = new byte[256 / 8];
    using (var random = RandomNumberGenerator.Create())
        random.GetBytes(bytes);
    return ToBase62String(bytes);
}

static string ToBase62String(byte[] toConvert)
{
    const string alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    BigInteger dividend = new BigInteger(toConvert);
    var builder = new StringBuilder();
    while (dividend != 0) {
        dividend = BigInteger.DivRem(dividend, alphabet.Length, out BigInteger remainder);
        builder.Insert(0, alphabet[Math.Abs(((int)remainder))]);
    }
    return builder.ToString();
}

1

Bir API anahtarı rastgele bir değer olmalıdır. Tahmin edilemeyecek kadar rastgele. Kullanıcının veya ait olduğu hesabın herhangi bir detayını içermemelidir. Oluşturulan kimliklerin rastgele olduğundan eminseniz UUID'leri kullanmak iyi bir fikirdir.

Örneğin Windows'un önceki sürümleri öngörülebilir GUID'ler üretti, ancak bu eski bir hikaye.


4
Windows 2000, rasgele sayılar kullanarak GUID'lere geçti . Bununla birlikte, rastgele sayıların tahmin edilemeyeceğinin garantisi yoktur. Örneğin, bir saldırgan kendisi için birkaç API anahtarı oluşturuyorsa, başka bir kullanıcının API anahtarını oluşturmak için kullanılacak gelecekteki rastgele bir sayıyı belirlemek mümkün olabilir. Genel olarak, UUID'lerin güvenli bir şekilde önlenemez olduğunu düşünmeyin .
Edward Brey
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.