日前对项目的交互协议进行了升级,使用JSON报文,优化加密交互流程,提高性能,优化报文数据量。
之前的协议框架参看http://my.oschina.net/kaster/blog/130940
客户端连接服务端,首先进行一次证书更新请求,服务端返回RSA公钥信息。
初始化完成后,客户端进行一次AES密钥交换请求,后续转入正常业务交互流程。
关键业务接口请求服务端会验证session签名。
用户登陆后会返回sessionId及sessionKey。
请求地址采用http://域名:端口/client/产品编号/渠道编号/接口编号/激活流水/ 方式访问服务端数据。
接口定向分发和负载均衡参看http://my.oschina.net/kaster/blog/134495
消息头结构:
请求消息头: { "head": { "command": "接口编号", "messageId": "消息流水", "activeId": "激活流水", "sessionId": "会话流水", "sessionSign": "会话签名" }, "dataMode": "数据模式", "body": "加密报文", "digest": "报文摘要" } 响应消息头: { "head": { "messageId": "消息流水", "result": "接口返回码", "resultDesc": "接口返回码描述" }, "dataMode": "数据模式", "body": "加密报文", "digest": "报文摘要" }
一:数据模式1:
该模式下, body密文 = Base64(明文),digest摘要=32位MD5(body密文)。
该接口用户非隐秘、小量数据的处理。
二:数据模式2:
该模式下,body密文 = Base64(ZIP(明文)),digest摘要=32位MD5(body密文)。
该接口用户非隐秘、大量数据的处理。
三:数据模式3:
该模式下,body密文 = Base64(AES(明文,AES _KEY)),digest摘要 = 32位MD5(body密文)。明文数据使用PKCS5规则进行补位,加密模式使用AES-ECB。
该接口用户隐秘、小量数据的处理。
四:数据模式4:
该模式下,body密文 = Base64(AES(ZIP(明文),AES _KEY)),digest摘要 = 32位MD5(body密文)。明文数据使用PKCS5规则进行补位,加密模式使用AES-ECB。
该接口用户隐秘、大量数据的处理。
每次交互都是用随机AES密钥对数据进行加密,所以对AES的密钥每次加密后,随报文头一并传输。报文头key字段=BASE64(RSA(AES_KEY明文,公钥))。
AES_KEY明文为AES随机密钥,采用128位密钥长度。具体一个长度32字节,由16进制字符组成的字符串, 如:1234567890ABCDEF1234567890ABCDEF使用时,相临的两位理解为一个16进制数的明文,然后转换为实际使用的8位密钥。
明文数据使用PKCS1规则进行补位,加密模式使用RSA-ECB。
关键交易接口服务端会验证session签名。
sessionSign = 32字节MD5(command + messageId + activeId + sessionId + sessionKey + digest)
请求消息体 空 响应消息体 { "rsaVersion": "公钥证书版本号(14字节字符串)", "rsaFileUrl": "RSA公钥证书下载地址", "expiresTime": "失效时间(14字节字符串)" }
请求消息体 { "version": "协议版本号", "clientId": "客户端产品编号", "channelId": "客户端渠道编号", "clientVersion": "客户端版本号", "deviceId": "设备唯一标识", "key": "客户端对称加密密钥" } 响应消息体 { "activeId ": "客户端激活流水", "expiresTime ": "密钥有效时间(14字节字符串)" }
注1:key字段为客户端AES密钥的密文,使用BASE64(RSA(AES_KEY,公钥)) 算法生成。
注2:AES密钥需要随机生成,为32字节字符串。
注3:客户端完成公钥证书检查工作(或跳过)后,先检查本地有无缓存AES密钥数据,如果无缓存,或是密钥有效时间已超时,则需要调用该接口重新交换AES随机密钥。
注4:接口会返回activeId,该字段需要放置到所有其它接口的包头之中。
注5:对于已超时失效的AES密钥,如果客户端使用缓存的AES密钥加密时,服务端会返回对应的错误,客户端需要重新调用该接口,进行AES密钥交换。
注6:如果客户端启动后,缓存的密钥有效,可以跳过该接口,直接使用缓存的激活流水和AES密钥进行交互。
注7:客户端升级后或清除缓存后,需要重新进行加密初始化。
注8:deviceId通过特定算法生成,设备固定。
请求消息体 { "loginName": "登陆用户名", "loginPassword": "32位MD5(登录密码)" } 响应消息体 { "result": "响应结果", "resultDesc": "响应结果描述", "sessionId":"会话编号", "sessionKey":"会话密钥" }
注1:像登陆接口使用加密模式3
优化后,客户端调用性能有明显提高,交互报文量也减少。
有关Session管理框架参见http://my.oschina.net/kaster/blog/130861
整个交互框架,使用到了RSA和AES加密,服务端保证私钥的安全性,保证用户隐私数据的安全。
加密交互框架代码示例参见http://www.oschina.net/code/snippet_1051910_21338