Позволете ми да започна, като кажа, че не съм експерт по криптографски алгоритми...
Опитвам се да създам метод, който форматира HTTP заглавка за Windows Azure - и тази заглавка изисква част от съобщението му да бъде шифровано чрез HMAC с SHA256 (и след това също кодирано base64).
Избрах да използвам CryptoJS, защото има активна потребителска общност.
Първо, моят код:
_encodeAuthHeader : function (url, params, date) {
//http://msdn.microsoft.com/en-us/library/windowsazure/dd179428
var canonicalizedResource = '/' + this.getAccountName() + url;
/*
StringToSign = Date + "\n" + CanonicalizedResource
*/
var stringToSign = date + '\n' + canonicalizedResource;
console.log('stringToSign >> ' + stringToSign)
var encodedBits = CryptoJS.HmacSHA256(stringToSign, this.getAccessKey());
console.log('encodedBits >> ' + encodedBits);
var base64Bits = CryptoJS.enc.Base64.stringify(encodedBits);
console.log('base64Bits >> ' + base64Bits);
var signature = 'SharedKeyLite ' + this.getAccountName() + ':' + base64Bits;
console.log('signature >> ' + signature);
return signature;
},
Методът успешно връща „подпис“ със съответната част криптирана/кодирана. Azure обаче се оплаква, че не е форматиран правилно.
Някои примерни резултати:
stringToSign >> Mon, 29 Jul 2013 16:04:20 GMT\n/senchaazurestorage/Tables
encodedBits >> 6723ace2ec7b0348e1270ccbaab802bfa5c1bbdddd108aece88c739051a8a767
base64Bits >> ZyOs4ux7A0jhJwzLqrgCv6XBu93dEIrs6IxzkFGop2c=
signature >> SharedKeyLite senchaazurestorage:ZyOs4ux7A0jhJwzLqrgCv6XBu93dEIrs6IxzkFGop2c=
Правейки отстраняване на грешки, забелязвам, че CryptoJS не връща същата стойност (HMAC с SHA256) като алтернативни реализации. Например низът "Mon, 29 Jul 2013 16:04:20 GMT\n/senchaazurestorage/Tables" се появява като:
- „6723ace2ec7b0348e1270ccbaab802bfa5c1bbdddd108aece88c739051a8a767“ чрез CryptoJS
- "faa89f45ef029c63d04b8522d07c54024ae711924822c402b2d387d05398fc9f" чрез PHP hash_hmac('sha256', ... )
Копаейки още по-дълбоко, виждам, че повечето HMAC/SHA265 алгоритми връщат данни, които съответстват на изхода от PHP... пропускам ли нещо в CryptoJS? Или има законна разлика?