2019/11/29 ypdai
前言
ceph的RGW对于s3的API,RGW支持V2和V4两种认证方式,其中V2方式支持本地认证、LDAP和keystone三种认证方式。V4方式兼容AWS V4认证机制。下面简单介绍下V2和V4两种认证方式中的本地认证模式中的计算签名的过程。
1、v2签名过程
整个过程大致分为下面3个部分。
1.1、生成签名字符串
- 把请求方法(GET、POST等)、请求header里面的指定字段(比如content-md5、content-type)全部拼接起来;
- 把请求header里面的以x-amz-或x-emc-开头的指定字段全部拼接起来;
- 把请求uri和请求参数全部拼接起来;
- 最后生成的签名字符串像这样:’GET\n\n\n\nx-amz-date:Fri, 29 Nov 2019 09:01:14 +0000\n/‘;
1.2、对第1步中生成的签名字符串加密处理
处理过程大致如下(string_to_sign表示第一步里面生成的签名字符串):
- 从配置文件里面获取用户的密钥secret_key。
- 把secret_key转为utf-8编码格式。
- 使用secret_key对string_to_sign加密处理得到签名字符串。
py里面加密代码如下:hmac.new(secret_key, string_to_sign, sha1).digest()。
- 最后把签名字符串转为unicode编码格式,类似这样:D2Lc+YvHo/EKBtpJTTLPhwEAP8s=。
1.3、拼接相关的信息,生成最后的签名字符串
最后的签名字符串为:”AWS “ + 用户的access_key + “:” + 第2步中生成的加密签名字符串。类似这样:AWS rgwuser02:D2Lc+YvHo/EKBtpJTTLPhwEAP8s=
。
2、v4签名过程
v4比v2的过程麻烦许多,总体的就是先计算出签名密钥
和签名字符串
,最后根据签名密钥
加密签名字符串
得到签名
。v2里面是直接根据用户密钥
加密签名字符串
得到签名
。
下面的过程把一些不重要的信息屏蔽了,大概的过程分为下面几个过程。
2.1、生成签名字符串
- 签名字符串 = 固定的’AWS4-HMAC-SHA256’字符串 + amzdate + credential_scope + canonical_request。
其中amzdate、credential_scope和canonical_request的值下面有说明。
- credential_scope = 时间戳 + region信息 + service信息 + 固定字符串’aws4_request’。
amzdate生成代码如下:
1
2t = datetime.datetime.utcnow()
amzdate = t.strftime('%Y%m%dT%H%M%SZ')canonical_request = 请求方法 + ‘请求地址 + 请求参数 + 请求headers + 固定字符串’’host;x-amz-content-sha256;x-amz-date’‘ + 请求body。
2.2、生成签名密钥
- 用户密钥加密时间戳得到v1。
- 使用上一步的v1加密region名称,默认为us-east-1,得到v2。
- 使用上一步的v2加密server名称,默认为s3,得到v3。
- 使用上一步的v3加密固定字符串’aws4_request’,得到签名密钥。
2.3、生成签名
最后使用签名密钥加密签名字符串,最后签名值大概是这样:AWS4-HMAC-SHA256 Credential=rgwuser02/20191202/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=9618ab3f255d76d475a05806a55148b860a84425923ba03ab4411f27794914c1
。