Javascript AWS:签名密钥版本4:如何使用Web加密API进行签名?

Javascript AWS:签名密钥版本4:如何使用Web加密API进行签名?,javascript,amazon-web-services,amazon-cognito,cryptojs,webcrypto-api,Javascript,Amazon Web Services,Amazon Cognito,Cryptojs,Webcrypto Api,对于我的webapp,我想直接从客户端与DynamoDB通信,而不需要中间API网关和Lambda。我不想只为几个http调用和密钥签名使用JSSDK。我偶然发现了一些针对几种语言的示例,但没有针对本机js模块。使用加密js的示例: Crypto.HmacSHA256(regionName, kDate); 我试过: const kSecret = '41575334774a616c725855746e46454d492f4b374d44454e472b6250785266694359455

对于我的webapp,我想直接从客户端与DynamoDB通信,而不需要中间API网关和Lambda。我不想只为几个http调用和密钥签名使用JSSDK。我偶然发现了一些针对几种语言的示例,但没有针对本机js模块。使用加密js的示例:

Crypto.HmacSHA256(regionName, kDate);
我试过:

const kSecret  = '41575334774a616c725855746e46454d492f4b374d44454e472b62507852666943594558414d504c454b4559',
    dateStamp = '20120215'


function _binaryToHex(array) {
    return array.map(b => ('00' + b.toString(16)).slice(-2)).join('');
}


/**
 * https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey
 */
async function _importKey(keyDataArrayBuffer) {
    return crypto.subtle.importKey(
        'raw',
        keyDataArrayBuffer,
        {'name': 'hmac', 'hash': {'name': 'SHA-256'}},
        false,
        ['sign']);
}

const kDate = _binaryToHex(
    Array.from(
        new Uint8Array(
            await crypto.subtle.sign(
                'HMAC',
                await _importKey(
                    new TextEncoder().encode(kSecret)
                ),
                new TextEncoder().encode(dateStamp)
            )
        )
    )
);
console.log(kDate);
/* Must be
 * '969fbb94feb542b71ede6f87fe4d5fa29c789342b0f407474670f0c2489e0a0d'
 */ 

但输出与示例中的不一样。

与往常一样,我必须细心周到-这里是简单的错误-输入键
kSecret
已编码为十六进制-但必须是原始的人类可读值


newtextcoder().encode('AWS4wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY')

如果您要在客户端应用程序中公开密钥,则只需将dynamo公开即可。你在伪安全性上浪费时间对不起,我忘了提到客户机有来自Cognito的用户密钥-我没有公开来自AWS帐户的密钥。Cognito id令牌和AWS密钥不是一回事。您不能互换使用它们。使用Cognito提供的
id\u令牌
,我将获得
IdentityId
,使用该令牌,我将获得具有
SecretKey
AccessKeyId
的用户的临时
凭证
,有效期为一小时。再次,这些与AWS IAM密钥/访问密钥对不同。您不能使用Cognito对dynamoDB进行身份验证。您可以使用它对API网关进行身份验证。