Desk.comのマルチパスSSOを自分のWebサイトに統合しようとしていますが、正しいHMAC-SHA1署名(エラーログなど)を生成するのに問題があります。Desk.comのWebサイトからの指示は次のとおりです。
- マルチパスAPIキーと完成したマルチパストークンを使用してSHA1HMACを構築します。
- Base64は、結果のHMACをエンコードします。
ログによると、私のマルチパストークンは正しいようです。まず、完全に機能するPHPのコード:
// Build an HMAC-SHA1 signature using the multipass string and your API key
$signature = hash_hmac("sha1", $multipass, $api_key, true);
// Base64 encode the signature
$signature = base64_encode($signature);
^ hash_hmacの「true」値は生のバイナリで情報を出力していることに注意してください-これが私のC#コードに当てはまるかどうかはわかりません
次に、正しく機能していない私のC#コード:
protected string getSignature(string multipass)
{
string api_key = "my_key_goes_here";
HMACSHA1 hmac = new HMACSHA1(Encoding.ASCII.GetBytes(api_key));
hmac.Initialize();
byte[] buffer = Encoding.ASCII.GetBytes(multipass);
string signature = BitConverter.ToString(hmac.ComputeHash(buffer)).Replace("-", "").ToLower();
return Convert.ToBase64String(Encoding.ASCII.GetBytes(signature));
}
これは、(文字通り)何時間にもわたって複数の異なる方法を検索して試した結果です。これを理解していただければ幸いです。
参照が必要な場合は、Desk.comの次のページを確認してください:http://dev.desk.com/docs/portal/multipass。コード例があり、コードを完成させるための手順の概要が示されています。
編集:これが私のマルチパス生成コードです。
protected string getMultipass(UserData user_data)
{
// Encode the data into a JSON object
JavaScriptSerializer s = new JavaScriptSerializer();
string json_data = s.Serialize(user_data);
// Acquire the Web.config appSettings
string site_key = "my_site_here";
string api_key = "my_key_here";
string iv = "OpenSSL for Ruby";
// Using byte arrays now instead of strings
byte[] encrypted = null;
byte[] bIV = Encoding.ASCII.GetBytes(iv);
byte[] data = Encoding.ASCII.GetBytes(json_data);
// XOR the first block (16 bytes)
// once before the full XOR
// so it gets double XORed
for (var i = 0; i < 16; i++)
data[i] = (byte)(data[i] ^ bIV[i]);
// Pad using block size of 16 bytes
int pad = 16 - (data.Length % 16);
Array.Resize(ref data, data.Length + pad);
for (var i = 0; i < pad; i++)
data[data.Length - pad + i] = (byte)pad;
// Use the AesManaged object to do the encryption
using (AesManaged aesAlg = new AesManaged())
{
aesAlg.IV = bIV;
aesAlg.KeySize = 128;
// Create the 16-byte salted hash
SHA1 sha1 = SHA1.Create();
byte[] saltedHash = sha1.ComputeHash(Encoding.UTF8.GetBytes(api_key + site_key), 0, (api_key + site_key).Length);
Array.Resize(ref saltedHash, 16);
aesAlg.Key = saltedHash;
// Encrypt using the AES managed object
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(data, 0, data.Length);
csEncrypt.FlushFinalBlock();
}
encrypted = msEncrypt.ToArray();
}
}
// Return the Base64-encoded encrypted data
return Convert.ToBase64String(encrypted, Base64FormattingOptions.None)
.TrimEnd("=".ToCharArray()) // Remove trailing "=" characters
.Replace("+", "-") // Change "+" to "-"
.Replace("/", "_"); // Change "/" to "_"
}