API 키 생성을위한 최상의 접근 방식


89

따라서 현재 다양한 서비스, Google API, Twitter API, Facebook API 등이 있습니다.

각 서비스에는 다음과 같은 API 키가 있습니다.

AIzaSyClzfrOzB818x55FASHvX4JuGQciR9lv7q

모든 키의 길이와 포함 된 문자가 다릅니다. API 키를 생성하는 가장 좋은 방법이 무엇인지 궁금합니다.

특정 언어, 키 생성에 대한 일반적인 접근 방식을 요구하는 것이 아닙니다. 사용자 앱의 세부 정보 암호화, 해시 또는 임의 문자열의 해시 등입니다. 해시 알고리즘에 대해 걱정해야합니까? (MSD, SHA1, bcrypt) 등?

편집 : 몇 명의 친구 (이메일 / 트위터)와 이야기를 나눴으며 대시가 제거 된 GUID를 사용하는 것이 좋습니다.

좀 더 많은 아이디어를 얻기를 바라면서 이것은 나에게 약간 엉망인 것처럼 보입니다.


나는 여기에 더 자세한 내용에 대답했다 .. 키 생성 및 hmac 인증으로 사용
Anshu Kumar

답변:


58

암호화 용으로 설계된 난수 생성기를 사용하십시오. 그런 다음 base-64로 숫자를 인코딩합니다.

다음은 C # 예제입니다.

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

2
이것은 매우 안전하지 않으며 데이터베이스에 액세스하는 공격자가 키를 얻을 수 있습니다. 서버 비밀과 결합하여 사용자에게 고유 한 것 (예 : 솔트)의 해시로 키를 생성하는 것이 좋습니다.
James Wierzba

13
임의로 생성 된 API 키를 저장하는 것은 해시 된 암호를 저장하는 것과 동일한 보안 특성을 갖습니다. 대부분의 경우 괜찮습니다. 당신이 제안했듯이, 무작위로 생성 된 숫자를 솔트라고 생각하고 서버 비밀로 해싱하는 것이 가능합니다. 그러나 이렇게하면 모든 유효성 검사에서 해시 오버 헤드가 발생합니다. 또한 모든 API 키를 무효화하지 않고 서버 비밀을 무효화하는 방법도 없습니다.
Edward Brey

좋은 해결책이지만 아마도 apiKey 앞에 var 키워드가 필요합니다. :) var apiKey = Convert.ToBase64String (key);
Dawid Ohia

@ JohnM2 맞아. 나는 apiKey다른 곳에서 선언 할 수 있었기 때문에 개방 된 상태로 두었습니다 . 명확성을 위해 유형을 추가했습니다.
Edward Brey

4
@JamesWierzba 공격 대상이 이미 데이터베이스에있는 경우 API에 대한 보안되지 않은 액세스를 갖는 것이 아마도 가장 우려할만한 문제 일 것입니다 ...
Jon Story

29

API 키에는 다음과 같은 속성이 있어야합니다.

  • 인증 된 API 사용자를 고유하게 식별합니다. "API 키"의 "키"부분
  • 해당 사용자 인증-추측 / 위조 불가
  • 사용자가 잘못 행동하면 취소 될 수 있습니다. 일반적으로 레코드를 삭제할 수있는 데이터베이스에 입력합니다.

일반적으로 수십억이 아닌 수천 또는 수백만 개의 API 키가 있으므로 다음을 수행 할 필요가 없습니다.

  • API 사용자에 대한 정보는 데이터베이스에 저장할 수 있으므로 안정적으로 저장합니다.

따라서 API 키를 생성하는 한 가지 방법은 다음 두 가지 정보를 가져 오는 것입니다.

  1. 고유성을 보장하는 일련 번호
  2. 키를 패딩하기에 충분한 임의 비트

개인 비밀을 사용하여 서명하십시오.

카운터는 사용자를 고유하게 식별하고 서명을 통해 위조를 방지합니다. 재 할당하려면 API 키 인증이 필요한 작업을 수행하기 전에 키가 데이터베이스에서 여전히 유효한지 확인해야합니다.

좋은 GUID 생성기는 여러 데이터 센터에서 키를 생성해야하거나 일련 번호를 할당하는 좋은 분산 방법이없는 경우 증분 카운터의 근사치입니다.


또는 임의의 문자열의 해시

해싱은 위조를 방지하지 않습니다. 서명 은 열쇠가 당신에게서 나왔다는 것을 보증하는 것입니다.


3
클라이언트가 제공 한 API 키가 API를 제공하는 서버에 이미 등록 된 API 키의 데이터베이스와 비교하여 확인되는 경우 알고리즘의 서명 단계가 필요합니까? 서버가 키를 제공하는 경우 서명이 중복되는 것처럼 보입니다.
sappenin

3
@sappenin, 네. 추측 할 수없는 키를 서버에 저장하면 위조를 방지 할 필요가 없습니다. 종종 API 요청은 머신 팜 중 하나에서 처리됩니다 . 서버는 여러 서버 중 하나입니다. 어떤 경우에는 경쟁 조건을 피할 수있는 데이터베이스로의 왕복없이 모든 시스템에서 서명 검사를 수행 할 수 있습니다.
Mike Samuel

1
@MikeSamuel API 키에 서명하고 데이터베이스로 왕복하지 않으면 키가 취소되었지만 API에 액세스하는 데 계속 사용되면 어떻게됩니까?
Abhyudit Jain

@AbhyuditJain, 모든 분산 시스템에서 일관성있는 메시지 순서 (해지 된 자격 증명의 후속 사용 전에 해지 발생 ) 또는 모호성을 제한하는 다른 방법이 필요합니다. 일부 시스템은 모든 요청에 ​​대해 왕복하지 않습니다. 노드가 데이터베이스에 키가 10 분 동안 있었다는 사실을 캐시하는 경우 10 분 밖에 없습니다. 공격자가 해지 된 자격 증명을 남용 할 수있는 창입니다. 하지만 혼란이 발생할 수 있습니다. 사용자가 자격 증명을 취소 한 다음 해당 자격 증명이 취소되었는지 테스트하고 고정되지 않은 세션으로 인해 두 요청이 다른 노드로 이동하기 때문에 놀랐습니다.
Mike Samuel

5

대시없이 소문자로 포맷 된 UUID를 사용합니다.

대부분의 언어에 내장되어 있기 때문에 생성이 쉽습니다.

API 키가 손상 될 수 있으며,이 경우 사용자가 API 키를 취소하고 새 키를 생성 할 수 있으므로 키 생성 방법이이 요구 사항을 충족 할 수 있어야합니다.


15
UUID가 추측하기 어렵다고 가정하지 마십시오. 보안 기능으로 사용해서는 안됩니다 (UUID 사양 RFC4122 섹션 6 ). API 키에는 보안 난수가 필요하지만 UUID는 안전하게 추측 할 수 없습니다 .
Edward Brey 2014-06-23

3
@EdwardBrey UUID uuid = UUID.randomUUID();Java에서는 어떻습니까? 랜덤이 충분하지 않다는 말인가요?
Micro

8
@MicroR 임의의 UUID는이를 만드는 데 사용 된 난수 생성기가 암호 학적으로 안전하고 128 비트로 충분한 경우에만 안전합니다. UUID RFC에는 보안 난수 생성기가 필요하지 않지만 주어진 구현에서 무료로 사용할 수 있습니다. randomUUID 의 경우 API 문서는 "암호 적으로 강력한 의사 난수 생성기"를 사용한다고 구체적으로 명시합니다. 따라서 특정 구현은 128 비트 API 키에 대해 안전합니다.
Edward Brey

4

영숫자 문자 만 포함 된 API 키를 원하는 경우 base-62 인코딩 만 대신 사용하는 base64-random 접근 방식 의 변형을 사용할 수 있습니다 . base-62 인코더는이를 기반으로 합니다 .

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

API 키는 임의의 값이어야합니다. 예측할 수 없을 정도로 무작위입니다. 사용자 또는 계정에 대한 세부 정보를 포함해서는 안됩니다. 생성 된 ID가 무작위라고 확신하는 경우 UUID를 사용하는 것이 좋습니다.

예를 들어 이전 버전의 Windows는 예측 가능한 GUID를 생성했지만 이것은 오래된 이야기입니다.


4
Windows 2000은 난수를 사용하여 GUID로 전환되었습니다 . 그러나 난수를 예측할 수 없다는 보장은 없습니다. 예를 들어 공격자가 자신을 위해 여러 API 키를 생성하는 경우 다른 사용자의 API 키를 생성하는 데 사용되는 미래의 난수를 확인할 수 있습니다. 일반적으로 UUID를 안전하게 추측 할 수 없다고 생각하지 마십시오 .
Edward Brey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.