auth

package module
v0.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 21, 2021 License: MIT Imports: 14 Imported by: 0

README

基于HTTP Header存储信息的签名方式

概述

本签名主要用于HTTP1.X情景下的请求,签名基于MD5/SHA1/SHA256(算法支持扩展)等,可配置的TTL时间范围(TTL使用绝对值计算,用来兼容客户端时间的漂移)。 签名内容涵盖Method、URI(不包含Host:Port信息,规避反向代理问题)、Body、时间戳四部分,基于Hash算法计算摘要,防止数据在传输中被篡改。

密钥问题

签名使用对称密钥,渠道接入前,需先申请签名密钥才可合法接入。 密码生成推荐使用1Password 1pwd.png

存储字段

使用HTTP中Proxy-Authorization、Date两个Header用来存储签名信息,其中

  • Proxy-Authorization存储签名,格式Prefix + Space + Base64(Digest),如
    SomSys R6iafFLDXS456Mgp9cqSqP2cUQhnwv28zfH4PVrBtR4=
    其中Prefix固定6位安全ASCII用来区分系统来源,Space(ASCII 32)表示分隔符,Base64编码哈希摘要。
  • Date存储时间戳,格式采用RFC1123 GMT格式,如Mon, 03 Aug 2020 19:31:55 GMT
    注:GMT使用UTC-0时区。

生成签名伪代码

依赖 hmac 算法

var method String = "POST" // method必须全部大写
var uri String = "/search?q=hmac&type=php" // 以https://github.com/search?q=hmac&type=php为例
var body ByteArray = ByteArray('{"key":"value"}') // 以JSON为例
var date String = "Mon, 03 Aug 2020 19:31:55 GMT" // 时间漂移±1分钟

buffer := NewBuffer() 
buffer.WriteString(method)
buffer.WriteString("|") // 分隔符1
buffer.WriteString(uri)
buffer.WriteString("|") // 分隔符2
buffer.WriteBytes(body) // body是以bytearray形式写入的
buffer.WriteString("|") // 分隔符3
buffer.WriteString(date)

// buffer.String() => POST|/search?q=hmac&type=php|{"key":"value"}|Mon, 03 Aug 2020 19:31:55 GMT

// 注:当body为空时(比如GET方法) buffer.String() => GET|/search?q=hmac&type=php||Mon, 03 Aug 2020 19:31:55 GMT

var prefix String = "SomSys" // 签名前缀,用于区分当前签名的归属渠道,需要提前申请。
var secret String = "8bcff8e4f5b7d6f7de2ccd92434fbd6f4ace29d1" // 签名密钥,需要提前申请。

// hmac算法,go/java/python/php/nodejs均支持,使用请查找对应语言的库。
hash := hmac.New(MD5/SHA1/SHA256, secret) // MD5/SHA1/SHA256 三种Hash算法选择
hash.Write(buffer.ByteArray())
var digest String = base64.EncodeToString(hash.Sum()) // Base64编码摘要

var Proxy-Authorization String = prefix + " " + digest // 注意要加一个空格分隔prefix和digest

http.Header.Set("Proxy-Authorization", Proxy-Authorization)
http.Header.Set("Date", date)

使用Shell编写

# 固定前缀
Prefix='Adummy'; \
# 固定密钥
Secret='czvZ1khr0XxLNiu8>v)V=~8toA5LJU'; \
# GMT格式时间戳
Date=$(TZ=GMT date '+%a, %d %b %Y %T %Z'); \
# 请求方法,对应 GET POST PUT PATCH DELETE
Method='POST'; \
# url参数
Parameters='desc=你好世界&nonce=0987654321'; \
# json格式的请求body
Body='{"Address":"南锣鼓巷","Memo":"尽快提车"}'; \
# 拼接并对url参数进行urlencode操作
URI='/dummy/hello?'$(python3 -c "import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1]))", $Parameters); \
# 使用|作为分隔符,拼接签名报文体
Payload=$Method'|'$URI'|'$Body'|'$Date; \
# 基于hmac-sha256进行签名,并以base64格式编码
Signature=$(echo -n $Payload | openssl dgst -sha256 -hmac $Secret -binary | base64); \
# 拼接签名前缀,注意要添加空格作为分隔
ProxyAuthorization=$Prefix' '$Signature; \
# 请求服务(参考testdata/dummy_server)
curl -X POST -H "proxy-authorization: $ProxyAuthorization" -H "date: $Date" -d "$Body" 'http://127.0.0.1:8080'$URI

Documentation

Index

Constants

View Source
const (
	// DefaultTTL default signature ttl
	DefaultTTL = time.Minute
	// IdentifierLen identifier's fix length
	IdentifierLen = 6
)
View Source
const (
	// GRPC the grpc method
	GRPC = "GRPC"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Identifier

type Identifier = string

Identifier distinguish what system is displayed, fix length is IdentifierLen

type Method

type Method interface {
	String() string
	Unknow() bool
	// contains filtered or unexported methods
}

Method define supproted http method

var (
	// MethodUnknow unknow
	MethodUnknow Method = &method{value: "UNKNOW"}
	// MethodGet http get
	MethodGet Method = &method{value: http.MethodGet}
	// MethodHead http head
	MethodHead Method = &method{value: http.MethodHead}
	// MethodPost http post
	MethodPost Method = &method{value: http.MethodPost}
	// MethodPut http put
	MethodPut Method = &method{value: http.MethodPut}
	// MethodPatch http patch
	MethodPatch Method = &method{value: http.MethodPatch}
	// MethodDelete http delete
	MethodDelete Method = &method{value: http.MethodDelete}
	// MethodConnect http connect
	MethodConnect Method = &method{value: http.MethodConnect}
	// MethodOptions http options
	MethodOptions Method = &method{value: http.MethodOptions}
	// MethodTrace http trace
	MethodTrace Method = &method{value: http.MethodTrace}
	// MethodGRPC grpc
	MethodGRPC Method = &method{value: GRPC}
)

func ToMethod added in v0.1.1

func ToMethod(method string) Method

ToMethod convert to method

type Option

type Option func(*option)

Option optional config

func WithMD5

func WithMD5() Option

WithMD5 use md5 hash algorithm

func WithSHA1

func WithSHA1() Option

WithSHA1 use sha1 hash algorithm

func WithSHA256

func WithSHA256() Option

WithSHA256 use sha256 hash algorithm

func WithSecrets

func WithSecrets(secrets map[Identifier]Secret) Option

WithSecrets setup mutli identifier-secret

func WithTTL

func WithTTL(ttl time.Duration) Option

WithTTL setup signature's ttl

type Secret

type Secret = string

Secret symmetric encryption cipher code

type Signature

type Signature interface {
	ResetSecrets(secrets map[Identifier]Secret) error
	Generate(identifier Identifier, method Method, uri string, body []byte) (authorization, date string, err error)
	Verify(authorization, date string, method Method, uri string, body []byte) (identifier Identifier, ok bool, err error)
}

Signature defines methods of signature

func NewSignature

func NewSignature(opts ...Option) (Signature, error)

NewSignature create a new signature instance

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL