您的位置:首页 > 其它

应用系统Url交互之数据加密

2015-09-24 16:00 225 查看
应用系统在通过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名称的由来。

标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符

为解决此问题,可采用一种用于URL的改进Base64编码,它在末尾填充'='号,并将标准Base64中的“+”和“/”分别改成了“-”和“_”,这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。

另有一种用于正则表达式的改进Base64变种,它将“+”和“/”改成了“!”和“-”,因为“+”,“*”以及前面在IRCu中用到的“[”和“]”在正则表达式中都可能具有特殊含义。

此外还有一些变种,它们将“+/”改为“_-”或“._”(用作编程语言中的标识符名称)或“.-”(用于XML中的Nmtoken)甚至“_:”(用于XML中的Name)。

二. 访问流程

下面以系统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字节的随机字符串

A访问B的完整过程描述

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

对密文BASE64解码:aes_msg=Base64_Decode(msg_encrypt)
使用AESKey做AES解密:rand_msg=AES_Decrypt(aes_msg)
验证解密后msg_len, systemNameA
去掉rand_msg头部的16个随机字节,4个字节的msg_len,和尾部的systemNameA即为最终的消息体原文msg
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: