网关设计基本流程以及签名算法处理、乱码处理方式

作者: admin 分类: 规则原理 发布时间: 2018-07-16 12:38  阅读: 372 views

一、网关接口调用的基本流程

二、签名规则 – 采用MD5加密方式

1. 访问时需要先创建用户,并创建APP,得到相应的app_key,app_secret

2. 客户端保存app_secret

3. 客户端请求时的格式为

url: http://ip:port/request.method?api=xx&paramA=&paramB=&….

header: token — 验证用户登录 【接口不需要登录时,无需传递】

uid — 当前用户 【接口操作属公共信息时,无需传递】

t — 时间戳 【保证请求的唯一性】

app_key –app的key 【和签名有关,并通过该值验证权限】

sign — 签名值 【签名验证时用到】

v — 版本号 【接口协议版本,和定义的接口信息有关,暂时未用到】

body: 请求内容

4. 如果url中带有中文,需要使用encodeURLcomponent进行编码。服务器端使用URLDecoder.decode进行解码

    body不编码。

5. 客户端的sign生成格式为

a. 根据API定义将url + header中的参数分为两部分。 A部分参与签名,B部分不参与签名

b. 将参数根据键的升序排序后格式化

方式一:【键和值】 paramA=aparamB=bparamC=c…

方式二:【只有值】 a#b#c#d…

c. 将格式化后的数据 拼接 app_secret

d. body先MD5加密后拼接字符串,参考阿里云相关的设计思路

e. 将拼接后的字符串 MD5加密

f. 转大写后传给服务端

6. 服务端的验签规则是

a. 和客户端的a、b规则一致

b. 根据header中的app_key获取app_secret

c. 和客户端 从c、d、e一致

d. 转大写后和客户端传来的值进行对比

7. 通过后参数签名验证成功

 

 

三、几种常见的加密、解密方式

1、原系统中用的是1+2的结合,步骤如下

a. 对request.getQueryString()参数进行utf-8转码

b. md5验证 ([request.getMethod()+request.getRequestURL()]+[param]+[request.getContentLength()]+[token]+[sign])

第一块:方法名 + 请求全路径[http://IP:端口/地址]

第二块:参数字符串 a=b&c=d&e=f get有效,post无效

第三块:请求体长度

第四块:token,访问令牌

第五块:客户端传来的sign信息,和前四块的进行对比处理

c. 不对request.getQueryString()参数进行utf-8转码

d.md5验证 ([request.getMethod()+request.getRequestURL()]+[param]+[request.getContentLength()]+[token]+[sign])

e. 将request.getRequestURL() 换成 request.getRequestURI() 重复上述步骤进行两次验证

弊端: 1. 如果调用服务是多个节点,IP随机访问;或做IP转发\代理时。request.getRequestURL()会导致验签失败

 

2、所接触的三方支付接口,【MD5方式】【3+4结合】

3、接触的银行存管API接口相关如下,参数组装方式和初版网关设计相似

  初版网关文档 存管方[AES + RSA]
参与签名内容 所有请求参数,header+url中的 分类,部分必选,部分可选
参数顺序 按照key正序排序 放到treemap中,自动排序
格式 k1=v1k2=v2 v1?v2?v3?v4 【通过某个特殊符号分割值】
附加 末尾加app_secret+token 无其他
加密 utf-8转码后MD5加密 base64转码后 RSA方式加密
  MD5性能高些,不需要解密,只需对比 RSA根据数据长度,解密时间会增加
    数据长度5000字节左右,正常响应

5、几种加密方式的对比

MD5 速度快、安全性中 计算简单,效率高,
AES 安全性高 内部系统适用。不对外开放,密钥管理比较安全
RSA 速度慢、安全性高 解密速度和数据长度有关。【没有经过验证,不明确速率多少】
RSA+AES 安全性高、速度快 逻辑复杂一点

 

5、目前较复杂的两种加密方式的基本流程

a. AES+RSA单向加密

 

步骤: 这个是单向

1. 服务器端创建RSA公私钥,服务器保留私钥。客户端保留公钥

2. 客户端创建AES密钥,加密传输数据

3. 用RSA公钥加密AES密钥

4. 将加密后的AES密钥和密文传递给服务器

5. 服务器端先根据RSA私钥解密已加密的AES密钥

6. 根据AES密钥解密密文得到明文

 

b.AES+RSA双向加密

 

1. 服务器端(server)和客户端(client)分别生成自己的密钥对

2. server和client分别交换自己的公钥

3. client生成AES密钥(aesKey)

4. client使用自己的RSA私钥(privateKey)对请求明文数据(params)进行数字签名

5. 将签名加入到请求参数中,然后转换为json格式

6. client使用aesKey对json数据进行加密得到密文(data)

7. client使用sever的RSA公钥对aesKey进行加密(encryptkey)

8. 分别将data和encryptkey作为参数传输给服务器端

服务器端进行请求响应时将上面流程反过来即可

 

四、中文乱码问题

一般处理方式

1. url参数为中文时传递到服务器是乱码, 需要对应的加码+解码处理

2. 中文带有特殊字符, 需要特殊处理【需要看客户端是调用的什么方法】

3. 响应值为乱码。 排除默认编码,解码处理

 

相关测试

js转码生成工具地址 http://tool.chinaz.com/tools/unicode.aspx

测试源字符串

String str = "是一个众筹网站【 】!空格,有@_@个性,有:)。";

// unicode格式

String unicode = "\u662f\u4e00\u4e2a\u4f17\u7b79\u7f51\u7ad9\u002c\u6709\u0040\u005f\u0040\u4e2a\u6027\u002c\u6709\u003a\u0029\u3002";

//escape格式

String escape_sequence = "是一个众筹网站,有@_@个性,有:)。";

//utf-8,encodeURI格式

String encodeURL =

"%E6%98%AF%E4%B8%80%E4%B8%AA%E4%BC%97%E7%AD%B9%E7%BD%91%E7%AB%99%E3%80%90%20%20%20%E3%80%91!%E7%A9%BA%E6%A0%BC,%E6%9C%89@_@%E4%B8%AA%E6%80%A7,%E6%9C%89:)%E3%80%82";

//utf-8,encodeURIcomponent格式

String component = "%E6%98%AF%E4%B8%80%E4%B8%AA%E4%BC%97%E7%AD%B9%E7%BD%91%E7%AB%99%E3%80%90%20%20%20%E3%80%91!%E7%A9%BA%E6%A0%BC%2C%E6%9C%89%40_%40%E4%B8%AA%E6%80%A7%2C%E6%9C%89%3A)%E3%80%82";

 

对应解释

unicode: 一个字符有个特定的码位

utf-8: 将「码位」转换为字节序列的规则

encode【

两函数采用UTF-8对URL进行编码

encodeUrl 注:不会编码字符 A-Z a-z 0-9 – _ . ! ~ * ' ( );/?:@&=+$,#

encodeURLcomponent 注:不会编码字符 A-Z a-z 0-9 – _ . ! ~ * ' ( )

escape_sequence 解释

类似&name;&#dddd; &#xhhhh; 的字符串是 HTML、XML 等 SGML 类语言的转义序列(escape sequence)。它们不是「编码」。

以 HTML 为例,这三种转义序列都称作 character reference:第一种是 character entity reference,后接预先定义的 entity 名称,而 entity 声明了自身指代的字符。

后两种是 numeric character reference(NCR),数字取值为目标字符的 Unicode code point;以「&#」开头的后接十进制数字,以「&#x」开头的后接十六进制数字。

 

相关连接

关于前端需要转码两次的说明【如:http://ip:port/request.method?api=xx&paramA=encodeUrl(encodeUrl(xxxx))&paramB=&….

https://blog.csdn.net/zqd_java/article/details/53924769

其他各种乱码问题处理方式一览

https://blog.csdn.net/haitianxiaowu1/article/details/52460105

 

 

五、签名相关参考地址

阿里云的签名说明

https://help.aliyun.com/document_detail/29012.html

腾讯云的签名说明 – 没有详尽

https://cloud.tencent.com/document/product/436/7778

微信支付的签名说明 – xml方式

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3

支付宝开放平台的签名说明 — 拼接整体签名

https://docs.open.alipay.com/291/106118


   原创文章,转载请标明本文链接: 网关设计基本流程以及签名算法处理、乱码处理方式

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注