将散列数据作为密钥再次散列 returns 不正确的结果
Passing hashed data as key to hash again returns incorrect results
我正在创建一个将使用 GAS 访问 AWS 服务的脚本。我正在使用 Utilities 库中的散列函数来进行创建 v4 签名所需的所有散列。这些函数似乎能够成功地散列数据一次,但尝试将散列数据传递到参数中会产生不正确的结果。还有其他人 运行 研究过这个问题并解决了这个问题吗?
我知道 Utilities.computeHmacSha256Signature( input, key ) 发生了一些奇怪的事情,因为参数只能是字节数组或字符串,我传递的是组合两者中的。但是,当我尝试将参数转换为字节数组或字符串时,我仍然没有运气。
我的密钥生成代码
设计参考:link
function getSignatureKey( key, dateStamp, regionName, serviceName ) {
var kSecret = 'AWS4' + key;
var kDate = hash( dateStamp, kSecret );
var kRegion = hash( regionName, kDate );
var kService = hash( serviceName, kRegion );
var kSigning = hash( 'aws4_request', kService );
return kSigning;
}
'My'哈希函数:
function hash( payload, key ) {
const utf8 = Utilities.Charset.UTF_8;
const sha256 = Utilities.DigestAlgorithm.SHA_256;
if ( !payload ) payload = '';
if ( key ) {
payload = Utilities.computeHmacSha256Signature( payload, key, utf8 );
}
else
payload = Utilities.computeDigest( sha256, payload, utf8 );
return payload;
}
示例输入
var key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY';
var date = '20150830';
var region = 'us-east-1';
var service = 'iam';
从示例输入生成的密钥 来自 link
c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9
逐步结果 由jsSHA
生成
// kDate = HMAC( date, 'AWS4' + key )
0138c7a6cbd60aa727b2f653a522567439dfb9f3e72b21f9b25941a42f04a7cd
// kRegion = HMAC( region, kDate )
f33d5808504bf34812e5fade63308b424b244c59189be2a591dd2282c7cb563f
// kService = HMAC( service, kRegion )
199e1f48c602a5ae77ce26a46906920e76fc8427aeaa53da643646fcda1ccfb0
// kSigning = HMAC( 'aws4_request', kService ) -- matches example
c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9
我的结果 运行上面hash()函数的结果(通过十六进制编码)
// var kSecret = 'AWS4' + key;
// var kDate = hash( dateStamp, kSecret )
0138c7a6cbd60aa727b2f653a522567439dfb9f3e72b21f9b25941a42f04a7cd
// var kRegion = hash( regionName, kDate );
67a1e58cdd80d4ae0eab4345f1cac6e4faab10efb9c21fd7b30e5e9118462c79
// var kService = hash( serviceName, kRegion );
295384288c76cdb665c1cbf8281250b93b6ae257b98b72e4be0876a9e8a0b409
// var kSigning = hash( 'aws4_request', kService );
bfb393756c5518b668b5055910bb715e4a879c0e10bb22d3140b1e82b2a50a2c
这个修改怎么样?
问题原因:
Utilities.computeHmacSha256Signature(value, key)
的value
和key
都是"String"或"Byte[]"。在您的脚本中,当 var kDate = hash( dateStamp, kSecret );
为 运行 时,kDate
为字节数组。但是当 var kRegion = hash( regionName, kDate );
是 运行 时,regionName
和 kDate
分别是 "String" 和 "Byte[]"。这样一来,var kRegion = hash( regionName, kDate );
后的结果就和jsSHA不一样了
修改点:
- 为了避免这种情况,例如,请将"String"转换为"Byte[]"。
修改后的脚本:
function sample() {
var key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY';
var dateStamp = '20150830';
var regionName = 'us-east-1';
var serviceName = 'iam';
var kSecret = 'AWS4' + key;
regionName = Utilities.newBlob(regionName).getBytes(); // Added
serviceName = Utilities.newBlob(serviceName).getBytes(); // Added
var value = Utilities.newBlob('aws4_request').getBytes(); // Added
var kDate = hash( dateStamp, kSecret );
var kRegion = hash( regionName, kDate );
var kService = hash( serviceName, kRegion );
var kSigning = hash( value, kService );
return kSigning;
}
function hash( payload, key ) {
return Utilities.computeHmacSha256Signature(payload, key);
// return Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, payload, key) // You can also use this.
}
结果:
kDate: 0138c7a6cbd60aa727b2f653a522567439dfb9f3e72b21f9b25941a42f04a7cd
kRegion: f33d5808504bf34812e5fade63308b424b244c59189be2a591dd2282c7cb563f
kService: 199e1f48c602a5ae77ce26a46906920e76fc8427aeaa53da643646fcda1ccfb0
kSigning: c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9
参考文献:
- computeHmacSha256Signature(value, key)
- computeHmacSignature(algorithm, value, key)
- newBlob(data)
- getBytes()
如果这不是你想要的,我很抱歉。
我正在创建一个将使用 GAS 访问 AWS 服务的脚本。我正在使用 Utilities 库中的散列函数来进行创建 v4 签名所需的所有散列。这些函数似乎能够成功地散列数据一次,但尝试将散列数据传递到参数中会产生不正确的结果。还有其他人 运行 研究过这个问题并解决了这个问题吗?
我知道 Utilities.computeHmacSha256Signature( input, key ) 发生了一些奇怪的事情,因为参数只能是字节数组或字符串,我传递的是组合两者中的。但是,当我尝试将参数转换为字节数组或字符串时,我仍然没有运气。
我的密钥生成代码 设计参考:link
function getSignatureKey( key, dateStamp, regionName, serviceName ) {
var kSecret = 'AWS4' + key;
var kDate = hash( dateStamp, kSecret );
var kRegion = hash( regionName, kDate );
var kService = hash( serviceName, kRegion );
var kSigning = hash( 'aws4_request', kService );
return kSigning;
}
'My'哈希函数:
function hash( payload, key ) {
const utf8 = Utilities.Charset.UTF_8;
const sha256 = Utilities.DigestAlgorithm.SHA_256;
if ( !payload ) payload = '';
if ( key ) {
payload = Utilities.computeHmacSha256Signature( payload, key, utf8 );
}
else
payload = Utilities.computeDigest( sha256, payload, utf8 );
return payload;
}
示例输入
var key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY';
var date = '20150830';
var region = 'us-east-1';
var service = 'iam';
从示例输入生成的密钥 来自 link
c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9
逐步结果 由jsSHA
生成// kDate = HMAC( date, 'AWS4' + key )
0138c7a6cbd60aa727b2f653a522567439dfb9f3e72b21f9b25941a42f04a7cd
// kRegion = HMAC( region, kDate )
f33d5808504bf34812e5fade63308b424b244c59189be2a591dd2282c7cb563f
// kService = HMAC( service, kRegion )
199e1f48c602a5ae77ce26a46906920e76fc8427aeaa53da643646fcda1ccfb0
// kSigning = HMAC( 'aws4_request', kService ) -- matches example
c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9
我的结果 运行上面hash()函数的结果(通过十六进制编码)
// var kSecret = 'AWS4' + key;
// var kDate = hash( dateStamp, kSecret )
0138c7a6cbd60aa727b2f653a522567439dfb9f3e72b21f9b25941a42f04a7cd
// var kRegion = hash( regionName, kDate );
67a1e58cdd80d4ae0eab4345f1cac6e4faab10efb9c21fd7b30e5e9118462c79
// var kService = hash( serviceName, kRegion );
295384288c76cdb665c1cbf8281250b93b6ae257b98b72e4be0876a9e8a0b409
// var kSigning = hash( 'aws4_request', kService );
bfb393756c5518b668b5055910bb715e4a879c0e10bb22d3140b1e82b2a50a2c
这个修改怎么样?
问题原因:
Utilities.computeHmacSha256Signature(value, key)
的value
和key
都是"String"或"Byte[]"。在您的脚本中,当 var kDate = hash( dateStamp, kSecret );
为 运行 时,kDate
为字节数组。但是当 var kRegion = hash( regionName, kDate );
是 运行 时,regionName
和 kDate
分别是 "String" 和 "Byte[]"。这样一来,var kRegion = hash( regionName, kDate );
后的结果就和jsSHA不一样了
修改点:
- 为了避免这种情况,例如,请将"String"转换为"Byte[]"。
修改后的脚本:
function sample() {
var key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY';
var dateStamp = '20150830';
var regionName = 'us-east-1';
var serviceName = 'iam';
var kSecret = 'AWS4' + key;
regionName = Utilities.newBlob(regionName).getBytes(); // Added
serviceName = Utilities.newBlob(serviceName).getBytes(); // Added
var value = Utilities.newBlob('aws4_request').getBytes(); // Added
var kDate = hash( dateStamp, kSecret );
var kRegion = hash( regionName, kDate );
var kService = hash( serviceName, kRegion );
var kSigning = hash( value, kService );
return kSigning;
}
function hash( payload, key ) {
return Utilities.computeHmacSha256Signature(payload, key);
// return Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, payload, key) // You can also use this.
}
结果:
kDate: 0138c7a6cbd60aa727b2f653a522567439dfb9f3e72b21f9b25941a42f04a7cd
kRegion: f33d5808504bf34812e5fade63308b424b244c59189be2a591dd2282c7cb563f
kService: 199e1f48c602a5ae77ce26a46906920e76fc8427aeaa53da643646fcda1ccfb0
kSigning: c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9
参考文献:
- computeHmacSha256Signature(value, key)
- computeHmacSignature(algorithm, value, key)
- newBlob(data)
- getBytes()
如果这不是你想要的,我很抱歉。