应用系统在通过url交互的时候,通常对传递的数据有一定的安全性要求,采用加密算法是比较常见的实现途径。
下面从通用角度,介绍我们的设计方法。
一. 建立注册中心
1) 注册中心为各个系统建立登记信息,定义系统名称,并且分配APIKey。系统使用这个APIKey来调用注册中心的服务,获取AccessToken.
2) 建立两两系统间的访问控制关系,数据加密采用AES算法,为它们动态分配密钥。A, B系统各自保存APIKey, 系统名称,密钥(Base64编码后)。
注:密钥可以由guid 动态生成,guid字符串去掉短横线,变成32个字符,对应256 bit的密钥长度,然后进行Base64编码,方便Url传输。
Base64 编码长度为 (32+1)/3 *4 = 44, 去掉末尾的补充的=号,则长度为43。 解码的时候,补充等号,还原成原来的32个字符。
Base64编码说明
Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。 如果剩下的字符不足3个字节,则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'='。转换后的字符串理论上将要比原来的长1/3
为了保证所输出的编码为可读字符,Base64制定了一个编码表,以便进行统一转换。编码表的大小为2^6=64,这也是Base64名称的由来。
二. 访问流程
下面以系统A访问系统B为例子,说明整个交互过程。
术语及说明:
1) msg 为要传递的数据
2) EncodingAESKey用于消息体的加密,长度固定为43个字符,从a-z, A-Z, 0-9共62个字符中选取,采用Base64解码后即为32字节长的AESKey。
AESKey=Base64_Decode(EncodingAESKey + “=”)
3) msg_encrypt 是加密后的消息体。按照下面的算法生成
Base64_Encode( AES_Encrypt[random(16B) + msg_len(4B) + msg + systemNameA] ),是对明文消息msg加密处理后的Base64编码。
其中random为16字节的随机字符串;
msg_len为4字节的msg长度,网络字节序;
msg为消息体明文;
systemNameA/B为注册的系统名称
4) msg_signature是签名,用于验证调用者的合法性。按照下面的算法生成
msg_signature=sha1(sort(accessToken、timestamp、nonce、systemNameA, msg_encrypt))。
sort的含义是将参数按照字母字典排序,然后从小到大拼接成一个字符串。
timestamp 为消息产生的时间戳,可以用1970-1-1以来的秒数表示
nonce 为16字节的随机字符串
1) A访问注册中心的API, 通过APIKey,A系统名,B系统名,换取AccessToken
2) 产生timestamp, nonce, 加密消息,然后签名生成msg_signature
3) 将accessToken、timestamp、nonce, systemNameA, msg_encrypt,msg_signature传递到SystemB
4) 按照相同的算法计算签名dev_msg_signature,和传递过来的签名msg_signature进行对比。如果相同,则数据合法
dev_msg_signature=sha1(sort(accessToken、timestamp、nonce、systemNameA, msg_encrypt))。
5) SystemB通过自己的APIKey,加上 accessToken,systemNameA,SystemNameB调用注册中心的API验证访问是否合法
6) 如果合法,则可以解密消息msg_encrypt