Asp.Net MVC3のRESTAPIサービスにHMAC-SHA署名アルゴリズムのようなAWSを実装したいと思います。ユーザーの公開キーとシークレットを生成するためのベストプラクティスはありますか?
1 に答える
同様のシステムを構築しました。@Jamesが参照する質問は、非常に優れた情報を提供します。必ずお読みください。可能であれば、SSL/TLSを介してのみサービスをデプロイしてください。
HMAC-SHA署名を使用すると、公開鍵は必要ありません。サーバー(サービス)とクライアントが共有する秘密鍵が1つあり、署名の計算に使用されます。上記のセキュリティサイトの質問に従って、クライアントごとに異なるキーがあることを確認してください。
クライアントごとに、クライアントを識別するために必要な他のIDとは異なる何らかのサービスクライアントIDも必要です。このサービスクライアントIDはリクエストヘッダーで送信されるため、クライアントを識別できます。クライアントを特定すると、クライアントのサービスキーなど、クライアントに関する必要な情報を取得できます。
サービスクライアントIDに加えて、リクエストヘッダーには生成された実際の署名が含まれている必要があります。また、ヘッダーにもタイムスタンプを含めることをお勧めします(これについては以下で詳しく説明します)。したがって、リクエストには次のようなヘッダーが含まれます。
MySvc-Clientid: ServiceId
MySvc-Signature: Signature
MySvc-Timestamp: TimeStamp
.NET / C#を使用してクライアントキーを生成するには、クライアントに配信できるRijndaelキーの文字列表現を生成するメソッドを作成できます。これが例です。
public string CreateServiceClientKey()
{
SymmetricAlgorithm symAlg = SymmetricAlgorithm.Create("Rijndael");
symAlg.KeySize = 128;
byte[] key = symAlg.Key;
StringBuilder sb = new StringBuilder(key.Length * 2);
foreach (byte b in key)
{
sb.AppendFormat("{0:x2}", b);
}
return sb.ToString();
}
私たちのシステムでは、新しいサービスクライアントが有効になると、サービスクライアントIDとサービスキーが生成され、クライアントのデータベースに保存されます。サービスクライアントIDは単なるGUIDである可能性があります。
クライアントのサービスキーは、ユーザーとクライアントの間で共有される秘密です。SSL / TLSで実行されているWebサイトの認証された部分など、安全なメカニズムを介してのみクライアントに配信します。それ以外の場合は、秘密鍵を取得している他の誰かに自分自身を開放します。
タイムスタンプはクライアントによって生成され、署名の生成元である署名の文字列に含まれている必要があります。これにより、シグニチャに時間固有の変動が追加されます。AWSもこれを行います。
署名する文字列に関しては、リクエストの署名と比較するときに、署名する文字列を作成するためにプログラムするインターフェイスを定義することもお勧めします。これにより、さまざまなサービスやさまざまな操作のためにさまざまな実装を構築できます。これは、実装に役立ちました。次に例を示します。
public interface IStringToSignBuilder
{
string Build(ServiceSignatureDetails details);
}
/// <summary>
/// Class is a data entity that defines the specific details
/// required for a Service Signature
/// </summary>
public class ServiceSignatureDetails
{
public string HttpMethod { get; set; }
public string ServiceClientId { get; set; }
public string ServiceClientKey { get; set; }
public string UriAbsolutePath { get; set; }
public string DomainName { get; set; }
public string CompanyName { get; set; }
public string DateTimeStamp { get; set; }
public string Data { get; set; }
}
次に、ニーズを満たす特定の実装を構築IStringToSignBuilder
し、それに応じて正しい実装をコードに挿入できます。