新しいAPIキーを生成するための最良のアプローチは何ですか?


92

そのため、現在、Google API、Twitter API、FacebookAPIなどのさまざまなサービスがあります。

各サービスには、次のようなAPIキーがあります。

AIzaSyClzfrOzB818x55FASHvX4JuGQciR9lv7q

すべてのキーの長さと含まれる文字は異なりますが、APIキーを生成するための最良のアプローチは何でしょうか?

特定の言語を求めているのではなく、キーを作成するための一般的なアプローチだけを求めています。それらは、ユーザーアプリの詳細の暗号化、ハッシュ、またはランダムな文字列のハッシュなどです。ハッシュアルゴリズムについて心配する必要があります。 (MSD、SHA1、bcrypt)など?

編集: 私は数人の友人(email / twitter)と話をしましたが、彼らはダッシュを取り除いたGUIDを使用することを勧めました。

これは私には少しハッキーに思えますが、もっとアイデアを得たいと思っています。


私はここでより詳細に答えました..キーを生成し、それをhmac認証として使用する
AnshuKumar20年

回答:


59

暗号化用に設計された乱数ジェネレーターを使用します。次に、base-64で数値をエンコードします。

これはC#の例です。

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

2
これはあまり安全ではありません。データベースにアクセスする攻撃者がキーを取得する可能性があります。サーバーシークレットと組み合わせて、ユーザーに固有の何か(ソルトなど)のハッシュとしてキーを生成することをお勧めします。
James Wierzba 2017

14
ランダムに生成されたAPIキーの保存には、ハッシュ化されたパスワードの保存と同じセキュリティ特性があります。ほとんどの場合、それは問題ありません。ご提案のとおり、ランダムに生成された番号をソルトと見なし、サーバーシークレットでハッシュすることができます。ただし、そうすることで、検証ごとにハッシュオーバーヘッドが発生します。また、すべてのAPIキーを無効にせずにサーバーシークレットを無効にする方法はありません。
エドワードブレイ2017

素晴らしい解決策ですが、おそらくapiKeyの前にvarキーワードが必要です:) var apiKey = Convert.ToBase64String(key);
DawidOhia18年

@ JohnM2そうです。apiKey他の場所で宣言できるので、私はそれをオープンエンドのままにしていました。わかりやすくするためにタイプを追加しました。
エドワードブレイ2018年

4
攻撃...そして、彼らはあなたのAPIへの無担保のアクセスを持つことは、おそらくあなたの懸念の少なくともある、あなたのデータベースにすでに含まれている場合@JamesWierzba
ジョンストーリー

30

APIキーには、次のようなプロパティが必要です。

  • 承認されたAPIユーザーを一意に識別します-「APIキー」の「キー」部分
  • そのユーザーを認証します-推測/偽造することはできません
  • ユーザーが誤動作した場合は取り消すことができます。通常、ユーザーはレコードを削除できるデータベースにキー入力します。

通常、数十億ではなく数千または数百万のAPIキーがあるため、次のことを行う必要はありません。

  • APIユーザーに関する情報はデータベースに保存できるため、確実に保存できます。

そのため、APIキーを生成する1つの方法は、次の2つの情報を取得することです。

  1. 一意性を保証するシリアル番号
  2. キーを埋めるのに十分なランダムビット

プライベートシークレットを使用して署名します。

カウンターは、ユーザーを一意に識別することを保証し、署名によって偽造を防ぎます。取り消し可能性では、APIキーの認証が必要な処理を行う前に、データベースでキーがまだ有効であることを確認する必要があります。

優れたGUIDジェネレーターは、複数のデータセンターからキーを生成する必要がある場合、またはシリアル番号を割り当てるための適切な分散方法がない場合に、増分カウンターのかなり適切な近似値です。


またはランダムな文字列のハッシュ

ハッシュは偽造を防ぎません。 署名は、鍵があなたから来たことを保証するものです。


3
クライアントによって提示されたAPIキーが、APIを提供するサーバーにすでに登録されているAPIキーのデータベースと照合される場合、アルゴリズムの署名手順は必要ですか?サーバーがキーを提供するサーバーである場合、ここでは署名が冗長になるようです。
sappenin 2015

3
@sappenin、はい。推測できないキーをサーバーに保存する場合は、偽造を防ぐ必要はありません。多くの場合、APIリクエストは、マシンの農場のいずれかによって処理される-サーバーは、多くのサーバーの1つです。署名チェックは、データベースへのラウンドトリップなしで任意のマシンで実行できるため、場合によっては競合状態を回避できます。
マイクサミュエル

1
@MikeSamuel APIキーが署名されていて、データベースへのラウンドトリップを行わない場合、キーが取り消されたがAPIへのアクセスに使用されているとどうなりますか?
Abhyudit Jain 2017

@AbhyuditJain、分散システムでは、一貫したメッセージの順序(取り消しが発生します-取り消された資格情報を後で使用する)またはあいまいさを制限する他の方法が必要です。一部のシステムは、すべてのリクエストでラウンドトリップするわけではありません。ノードがキーがデータベースに10分間存在したという事実をキャッシュする場合、10分しかありません。攻撃者が取り消された資格情報を悪用できるウィンドウ。ただし、混乱が生じる可能性があります。ユーザーが資格情報を取り消してから、取り消されたことをテストします。非スティッキーセッションでは、2つのリクエストが異なるノードに送られるため、驚いています。
マイクサミュエル

5

ダッシュなしで小文字にフォーマットされたUUIDを使用します。

ほとんどの言語に組み込まれているため、生成は簡単です。

APIキーが危険にさらされる可能性があります。その場合、ユーザーはAPIキーをキャンセルして新しいキーを生成する可能性があるため、キー生成メソッドはこの要件を満たすことができる必要があります。


15
UUIDを推測するのが難しいと思い込まないでください。これらはセキュリティ機能として使用しないでください(UUID仕様RFC4122セクション6)。APIキーには安全な乱数が必要ですが、UUIDは安全に推測できないわけではありません
エドワードブレイ2014年

3
@EdwardBrey UUID uuid = UUID.randomUUID();Javaではどうですか?ランダムでは不十分だと言っていますか?
マイクロ

8
@MicroRランダムUUIDは、それを作成するために使用される乱数ジェネレーターが暗号的に安全であり、128ビットで十分である場合にのみ安全です。UUID RFCは安全な乱数ジェネレーターを必要としませんが、特定の実装では自由に使用できます。randomUUIDの場合、APIドキュメントには、「暗号的に強力な疑似乱数ジェネレーター」を使用すると具体的に記載されています。そのため、特定の実装は128ビットAPIキーに対して安全です。
エドワードブレイ

4

英数字のみのAPIキーが必要な場合は、base64-randomアプローチの変形を使用できますが、代わりにbase-62エンコーディングのみを使用します。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が安全に推測できないとは考えないでください
エドワードブレイ2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.