移动客户端与服务端的安全交互(二次优化)

日前对项目的交互协议进行了升级,使用JSON报文,优化加密交互流程,提高性能,优化报文数据量。

之前的协议框架参看http://my.oschina.net/kaster/blog/130940


交互流程

客户端连接服务端,首先进行一次证书更新请求,服务端返回RSA公钥信息。

初始化完成后,客户端进行一次AES密钥交换请求,后续转入正常业务交互流程。

关键业务接口请求服务端会验证session签名。

用户登陆后会返回sessionIdsessionKey

请求地址采用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摘要=32MD5(body密文)

       该接口用户非隐秘、小量数据的处理。

二:数据模式2

       该模式下,body密文 = Base64(ZIP(明文))digest摘要=32MD5(body密文)

该接口用户非隐秘、大量数据的处理。

三:数据模式3

       该模式下,body密文 = Base64(AES(明文,AES _KEY))digest摘要 = 32MD5body密文)。明文数据使用PKCS5规则进行补位,加密模式使用AES-ECB

该接口用户隐秘、小量数据的处理。

四:数据模式4

       该模式下,body密文 = Base64(AES(ZIP(明文),AES _KEY))digest摘要 = 32MD5body密文)。明文数据使用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字节字符串)"
}



1key字段为客户端AES密钥的密文,使用BASE64(RSA(AES_KEY,公钥)) 算法生成。

2AES密钥需要随机生成,为32字节字符串。

3:客户端完成公钥证书检查工作(或跳过)后,先检查本地有无缓存AES密钥数据,如果无缓存,或是密钥有效时间已超时,则需要调用该接口重新交换AES随机密钥。

4:接口会返回activeId,该字段需要放置到所有其它接口的包头之中。

5:对于已超时失效的AES密钥,如果客户端使用缓存的AES密钥加密时,服务端会返回对应的错误,客户端需要重新调用该接口,进行AES密钥交换。

6:如果客户端启动后,缓存的密钥有效,可以跳过该接口,直接使用缓存的激活流水和AES密钥进行交互。

7:客户端升级后或清除缓存后,需要重新进行加密初始化。

8deviceId通过特定算法生成,设备固定。



业务接口

用户登录

请求消息体
{
    "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




你可能感兴趣的:(移动互联网,安全交互)