WSSE認証に利用する認証用文字列を作成します。(HTTPのX-WSSEヘッダを使用した認証)
WSSE認証は、HTTPのX-WSSEヘッダを使用した認証方式です。認証文字列は、ユーザー名とSHA1ハッシュされたパスワードで構成されるためパスワードが平文で流れる基本認証よりセキュアな認証が行えます。
WSSE認証は、はてなでよく使われています。HTTPSの場合は、通信自体が暗号化されるので不要ですがHTTP上でセキュアな認証という場合に使えます。
はてなサービスにおけるWSSE認証
http://developer.hatena.ne.jp/ja/documents/auth/apis/wsse
X-WSSEヘッダは以下の4つにより構成されます。
・Username
ユーザー名
・Nonce
HTTPリクエスト毎に生成したセキュリティ・トークン。40Byte程度のランダムな値を使っておけば良いと思います。
乱数を作ります。(System.Random, RNGCryptoServiceProvider) - tekkの日記 C#,VB.NET
・Created
Nonceが作成された日時をISO-8601表記で記述したもの ex("2011-02-20T22:34:57Z"
・PasswordDigest
Nonce+Created+パスワードをもとにSHA1アルゴリズムでダイジェスト化して生成された文字列を、Base64エンコードした文字列
X-WSSE: UsernameToken Username="tekk", PasswordDigest="9+aSsprBebWjLabUCJ3GhuAK8
/8=", Nonce="KQWjQSHncGhgrTnUADq9JqGi+oksUTg/MMazyKdQUDNLSeeuWz/ZbQ==", Created=
"2011-02-20T22:52:02Z"
以下、サンプルコードです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;namespace MakeWSSEHeader
{
class Program
{
static void Main(string[] args)
{const string USER_NAME = "tekk";
const string PASS_WORD = "tekkpw";// nonce security token
byte[] nonce = MakeRandomBytes(40);// created ISO-8601 formatting
string created = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssZ");// password sha1 digest (nonce+created+password)
ListlstByte = new List (); lstByte.AddRange(nonce);
lstByte.AddRange(System.Text.Encoding.UTF8.GetBytes(created));
lstByte.AddRange(System.Text.Encoding.UTF8.GetBytes(PASS_WORD));SHA1Managed sha1 = new SHA1Managed();
byte[] passwordDigest = sha1.ComputeHash(lstByte.ToArray());
// Build WSSE Header
string format = "X-WSSE: UsernameToken Username=\"{0}\", PasswordDigest=\"{1}\", Nonce=\"{2}\", Created=\"{3}\"";
string wsseHeader = String.Format(format,
USER_NAME,
Convert.ToBase64String(passwordDigest),
Convert.ToBase64String(nonce), created);Console.WriteLine(wsseHeader);
Console.ReadLine();}
static byte[] MakeRandomBytes(int makebytes)
{RNGCryptoServiceProvider rnd = new RNGCryptoServiceProvider();
Byte[] rndBuffer = new Byte[makebytes];
rnd.GetBytes(rndBuffer);return rndBuffer;
}
}
}