HTTP请求签名

2018-07-15  本文已影响1448人  show16

https://tools.ietf.org/id/draft-cavage-http-signatures-01.html#header

签名HTTP请求:提供了一个方法对服务端和客户端使用数字签名同时添加认证和消息集成到HTTP请求中。标准化方法。

1 简介

这个协议扩展是为了提供简单和标准的方法为客户端去签名HTTP请求
现状:
HTTP Authentication: basic和digest认证机制
TLS1.2: 传输层安全
OAuth2: Web服务请求的可选授权
这个协议是签名HTTP请求自身。

2 签名认证协议

签名认证协议依赖于这个模型客户端必须证实它自己利用一个数字签名,这个数字签名被提供通过非对称密钥(RSA)或者一个共享的对称密钥(HMAC)。这个协议是标准化的不依赖于任何签名算法或者密钥。然而它假设客户端可以发送一个 HTTP Date 头部。

2.1 Authorization Header

客户端被期待发送一个Authenrization头部(RFC 2617)用下面的变量:
credentials := "Signature" SP params
params := keyId "," algorithm [", " headers] [", " ext] ", " signature

keyId := "keyId" "=" plain-string
algorithm := "algorithm" "=" DQUOTE ( rsa-sha1 / rsa-sha256 / rsa-sha512 /
dsa-sha1 / hmac-sha1 / hmac-sha256 /
hmac-sha512 )
DQUOTE
headers := "headers" "=" plain-string
ext := "ext" "=" plain-string
signature := "signature" "=" plain-string

plain-string = DQUOTE *( %x20-21 / %x23-5B / %x5D-7E ) DQUOTE

2.1.1 签名变量

下面的小节详细描述了Authorization的签名变量


default

2.1.2 签名字符串构造

为了构造签名字符串,client必须按照headers定义的顺序取出每一个请求头部的值。每一个服务提供者至少应该包括 request line,host和date headers。

  1. 如果header名字不是 reqest-line,那么就附加一个小写的头部名称跟随一个 ascii 字符集分号 : 和一个ASCII 空格 .
  2. 如果header名称是 request-line,那么追加 http 请求行,否则附加 头部值。
  3. 如果值不是最后的值那么附加 ASCII 新行 \n.这个字符串必须不包括一个结尾的 ASCII新行。

POST /foo HTTP/1.1
Host: example.org
Date: Tue, 07 Jun 2014 20:51:35 GMT
Content-Type: application/json
Digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=
Content-Length: 18

{"hello": "world"}

下面的章节使用 http请求作为一个例子。
下面的章节也假设 "rsa-key-1" keyId代表一个私钥被客户端知道,一个公钥被服务端知道。 "hmac-key-1" keyId代表了一个密钥客户端和服务端都知道。

2.1.2.1. RSA例子

请求头部:
POST /foo HTTP/1.1\n
host: example.org\n
date: Tue, 07 Jun 2014 20:51:35 GMT\n
digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=\n
content-length: 18

请求签名:
Authorization: Signature keyId="rsa-key-1",algorithm="rsa-sha256",
headers="request-line host date digest content-length",
signature="Base64(RSA-SHA256(signing string))"

2.1.2.2. HMAC例子

请求头部:
POST /foo HTTP/1.1\n
host: example.org\n
date: Tue, 07 Jun 2014 20:51:35 GMT\n
digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=\n
content-length: 18

请求签名:
Authorization: Signature keyId="hmac-key-1",algorithm="hmac-sha1",
headers="request-line host date digest content-length",
signature="Base64(HMAC-SHA1(signing string))"

这2个例子的唯一的差别在于使用的算法不一样。客户端会组合 signing string用相同的方法。

3 附录A: 安全上的考虑

There are a number of security considerations to take into account when implementing or utilizing this specification. A thorough security analysis of this protocol, including its strengths and weaknesses, can be found in Security Considerations for HTTP Signatures.

4 附录B: 扩展

这个说明书被设计成简单,模块化和可扩展的。这里有许多其它的说明书依据这个文档定义的。For example, the HTTP Signature Nonces specification details how to use HTTP Signatures over a non-secured channel like HTTP and the HTTP Signature Trailers specification explains how to apply HTTP Signatures to streaming content. Developers that desire more functionality than this specification provides are urged to ensure that an extension specification doesn't already exist before implementing a proprietary extension.

5 附录C:测试例子

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C3
6rPJj+CvfSC8+q28hxA161QFNUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6
Z4UMR7EOcpfdUE9Hf3m/hs+FUR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJw
oYi+1hqp1fIekaxsyQIDAQAB
-----END PUBLIC KEY-----

-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDCFENGw33yGihy92pDjZQhl0C36rPJj+CvfSC8+q28hxA161QF
NUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6Z4UMR7EOcpfdUE9Hf3m/hs+F
UR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJwoYi+1hqp1fIekaxsyQIDAQAB
AoGBAJR8ZkCUvx5kzv+utdl7T5MnordT1TvoXXJGXK7ZZ+UuvMNUCdN2QPc4sBiA
QWvLw1cSKt5DsKZ8UETpYPy8pPYnnDEz2dDYiaew9+xEpubyeW2oH4Zx71wqBtOK
kqwrXa/pzdpiucRRjk6vE6YY7EBBs/g7uanVpGibOVAEsqH1AkEA7DkjVH28WDUg
f1nqvfn2Kj6CT7nIcE3jGJsZZ7zlZmBmHFDONMLUrXR/Zm3pR5m0tCmBqa5RK95u
412jt1dPIwJBANJT3v8pnkth48bQo/fKel6uEYyboRtA5/uHuHkZ6FQF7OUkGogc
mSJluOdc5t6hI1VsLn0QZEjQZMEOWr+wKSMCQQCC4kXJEsHAve77oP6HtG/IiEn7
kpyUXRNvFsDE0czpJJBvL/aRFUJxuRK91jhjC68sA7NsKMGg5OXb5I5Jj36xAkEA
gIT7aFOYBFwGgQAQkWNKLvySgKbAZRTeLBacpHMuQdl1DfdntvAyqpAZ0lY0RKmW
G6aFKaqQfOXKCyWoUiVknQJAXrlgySFci/2ueKlIE1QqIiLSZ8V8OlpFLRnb1pzI
7U1yQXnTAEFYM560yJlzUpOb1V4cScGd365tiSMvxLOvTA==
-----END RSA PRIVATE KEY-----

它们使用的测试请求是:
POST /foo?param=value&pet=dog HTTP/1.1
Host: example.com
Date: Thu, 05 Jan 2014 21:31:40 GMT
Content-Type: application/json
Digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=
Content-Length: 18

{"hello": "world"}

5.1 默认测试

默认测试请求头部中只包含 date
date: Thu, 05 Jan 2014 21:31:40 GMT

那么授权头部是:
Authorization: Signature keyId="Test",algorithm="rsa-sha256",
signature="ATp0r26dbMIxOopqw0OfABDT7CKMIoENumuruOtarj8n/97Q3htH
FYpH8yOSQk3Z5zh8UxUym6FYTb5+A0Nz3NRsXJibnYi7brE/4tx5But9kkFGzG+
xpUmimN4c3TMN7OFH//+r8hBf7BT9/GmHDUVZT2JzWGLZES2xDOUuMtA="

5.2 基础测试

最小化的数据包含 request-line,host,和 date
POST /foo?param=value&pet=dog HTTP/1.1
host: example.com
date: Thu, 05 Jan 2014 21:31:40 GMT

授权头部是:
Authorization: Signature keyId="Test",algorithm="rsa-sha256",
headers="request-line host date", signature="KcLSABBj/m3v2Dhxi
CKJmzYJvnx74tDO1SaURD8Dr8XpugN5wpy8iBVJtpkHUIp4qBYpzx2QvD16t8X
0BUMiKc53Age+baQFWwb2iYYJzvuUL+krrl/Q7H6fPBADBsHqEZ7IE8rR0Ys3l
b7J5A6VB9J/4yVTRiBcxTypW/mpr5w="

5.3 所有的头部测试

强签名包含了所有的头部和一个HTTP请求Body的摘要
POST /foo?param=value&pet=dog HTTP/1.1
host: example.com
date: Thu, 05 Jan 2014 21:31:40 GMT
content-type: application/json
digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=
content-length: 18

Authorization: Signature keyId="Test",algorithm="rsa-sha256",
headers="request-line host date content-type digest content-length",
signature="jgSqYK0yKclIHfF9zdApVEbDp5eqj8C4i4X76pE+XHoxugXv7q
nVrGR+30bmBgtpR39I4utq17s9ghz/2QFVxlnToYAvbSVZJ9ulLd1HQBugO0j
Oyn9sXOtcN7uNHBjqNCqUsnt0sw/cJA6B6nJZpyNqNyAXKdxZZItOuhIs78w="

6 后记:

目前各大云厂商的HTTP请求签名都是基于此协议做的变种。例如阿里云的全签(加上了signatureNonce防重放)以及其它云厂商的简单签名。

https://help.aliyun.com/document_detail/29475.html?spm=a2c4g.11186623.2.4.rRiQlL

https://cloud.tencent.com/document/product/628/11819

上一篇下一篇

猜你喜欢

热点阅读