将AWS KMS非对称密钥签名/验证签名编码为base64并进行验证



我使用AWS KMS非对称ECC(ES256(密钥在Python3中使用API调用对令牌进行签名和验证。响应返回

{
"KeyId": "arn:aws:kms:us-east-1:000000000000:key/1234",
"Signature": "b'0D\x02 \x18\xd9\x13\x96\x9d\xb00p\xc9H\'-\xc6@{\xd1V\xf5\xeb\x83"1\x0e:\x98\xb4\xea6P\x0f\xdf\x82\x02 \x1fPt\xc0\x81pB\xaa\xe7_\xf2~\x91BlU\x05\xba1\xe0\xfe\xf6\xe4\xebL\nl\xfc\xf8\xce\xc6_'",
"SigningAlgorithm": "ECDSA_SHA_256" 

}

如果我使用AWS CLI;签名";是base64编码的:

{
"KeyId": "arn:aws:kms:us-east-1:000000000000:key/1234",
"Signature": "MEQCIBqjAiAnMKkugooWU6/AqCyfhQUocoiVeIIf8lL2p7YbAiBEJOl2cp9HzQNufiMBezIjZuSGW6ID13l7JSzTgLlv+g==",
"SigningAlgorithm": "ECDSA_SHA_256"
}

每当我试图对CCD_ 1进行base64编码时;签名";使用Python3中的API响应,我无法验证签名。以下是我收到的错误示例:

调用Verify时发生错误(InvalidKeyUsageException(操作:asn1:结构错误:标记不匹配(16对{class:1标签:2长度:39 isCompound:true}({可选:false显式:falseapplication:false private:false defaultValue:标记:字符串类型:0时间类型:0集合:false省略空:false}ecdsaSignature@2

如何对";签名";从API返回的字节字符串,并且仍然能够验证?

更新:

如果我更新到base64.b4encode而不是base64.urlsafe_encode,我会得到相同的结果:

def _sign_token(self, key_id, message):
signature = kms_client.sign(
KeyId=key_id,
Message=message,
MessageType="RAW",
SigningAlgorithm="ECDSA_SHA_256",
)
logger.log(msg=signature, level=cl.log_level)
return base64.b64encode(signature["Signature"]).decode()

日志消息返回:

{"asctime":"2021-04-03 19:40:27593","levelname":"INFO","name":"util.sign"lineno":214;消息":null;env":"局部"KeyId":"arn:aws:kms:us-east-1:0000000000000:key/309d8dc5-409e-4f57-96a8-c71223c84dc2";,"签名":"b'0E\x02!\x00\xcc\x82\xf4$@?\x9e\n\xd7$\x94\x9f。\x1d5\x19\x0c\x18\xab?\x93\xd5\x8Cx\xx6\x0c\x1b\xcf\xd9\xd9\ xd2\xd4";\xcf\x94\xede_>\x8c\x01~J\xea\x0ezB’";,"SigningAlgorithm":"ECDSA_SHA_256"ResponseMetadata":{"HTTPStatusCode":200,"HTTPHeaders":{"content-type":"application/x-amz-json-1.1"内容长度":"233〃"连接":"关闭"访问控制允许起源":"&";,"访问控制允许方法":"HEAD、GET、PUT、POST、DELETE、OPTIONS、PATCH";,"访问控制允许报头":"授权、内容类型、内容长度、内容-md5、高速缓存控制、x-amz-content-sha256、x-amz日期、x-amz-security-token、x-amz-user-agent、x-amx-target、x-amz/acl、x-am-z-version-id、x-localstack-target、x-amy-tagging"访问控制公开报头":"x-amz版本-id"日期":"星期六,032021年4月19:40:27 GMT"服务器":"hypercorn-h11〃}"重试次数:0}}

验证错误:

"stacktrace":"当调用Verify操作:asn1:结构错误:标记不匹配(16 vs{class:1 tag:13 length:69 isCompound:false}({optional:false显式:false应用程序:false私有:false默认值:标记:字符串类型:0时间类型:0集合:false省略空:false}ecdsaSignature@2";

def _verify_signature(self, key_id, message, signature):
response = kms_client.verify(
KeyId=key_id,
Message=message,
MessageType="RAW",
Signature=signature,
SigningAlgorithm="ECDSA_SHA_256",
)
logger.log(msg=response, level=cl.log_level)
return response

client.verify要求签名为字节https://boto3.amazonaws.com/v1/documentation/api/1.11.4/reference/services/kms.html#KMS.Client.verify

如果我放弃.encode(),我会得到相同的:

"stacktrace":"当调用Verify操作:asn1:结构错误:标记不匹配(16 vs{class:1 tag:13 length:69 isCompound:false}({optional:false显式:false应用程序:false私有:false默认值:标记:字符串类型:0时间类型:0集合:false省略空:false}ecdsaSignature@2";

def _sign_token(self, key_id, message):
signature = kms_client.sign(
KeyId=key_id,
Message=message,
MessageType="RAW",
SigningAlgorithm="ECDSA_SHA_256",
)
logger.log(msg=signature, level=cl.log_level)
return base64.b64encode(signature["Signature"])

注:

如果我通过客户端签名响应";签名";对于不使用base64编码的client.verify,验证通过

AWS cli编码的字符串是而不是urlsafe-base64编码的!它使用标准base64(即base64.b64encode(进行编码。

标准base64编码使用三个元字符/+=/base64.urlsafe_b64encode(string)0在路径或查询字符串中使用都不安全,URL安全编码将这两个分别替换为_-。由于/+存在于AWS CLI编码的字符串中,因此可以推断它使用标准的base64编码,而不是URL安全编码。

base64.b64encode的返回值为bytes对象。通常使用Base-64编码将二进制文件编码为文本。要获得文本形式的值,您需要decodeit(例如,将UTF-8转换为unicode字符串(:

base64_encoded_as_str = base64.b64encode(binary_value).decode()

AWS的支持过程发挥了作用。事实证明,当我试图验证而不是base64.b64decode()时,我正在对base64编码的签名进行decode()操作

最新更新