Security - 安全
安全说明
数据交互使用标准的 RSA 加密解密加签验签的模式。
客户端和服务端各自生成一对儿 RSA (1024) 公钥私钥,并互相交换公钥。
可以使用 openssl 工具生成 RSA 密钥对,示例:
# 生成私钥
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:1024
# 导出公钥
openssl rsa -pubout -in private_key.pem -out public_key.pem
也可以参考其它编程语言和工具生成 RSA 密钥对。
安全原则
在调试安全规范时,需要遵循以下原则:
- 保留私钥,互换公钥
- 明文加密,密文加签
- 公钥加密,私钥解密
- 私钥加签,公钥验签
接口形式
普通接口均为 https + post + json 形式的请求。 即:
- 请求协议:
https - 请求方式:
POST - 请求标头:
Content-Type: application/json
个别接口可能会有特殊的请求方式,具体请参考接口文档。
安全流程
以下流程中的 对方 是指请求的服务提供方,我方 是指请求的服务消费方。
在正向请求(接口调用)(agency => fire)中,对方 是 fire ,我方 是 agency 。
在反向请求(数据推送)(fire => agency)中,对方 是 agency ,我方 是 fire 。
在请求和响应的过程中,需要遵循以下流程:
发起请求
- 使用对方的公钥
public-key对请求参数的 json 对象的序列化的字符串加密,得到密文cipher - 将
cipher赋值于 request 的 body 的 json 对象的param属性,完成加密 - 使用我方的私钥
private-key将param的值(密文)加签得到签名sign - 将签名
sign赋值于 request 的 header 的自定义键值X-Sign中,完成加签 - 以上数据和 header 中的
X-Security和X-Client和X-Time和X-Trace一起发送给对方
接收数据
- 我方读取对方 response 的 header 的
X-Sign得到响应数据的签名sign - 我方读取对方 response 的 body 的 json 的
data得到响应数据的密文 - 使用对方的公钥
public-key对密文data和签名sign进行验签 - 验签成功之后,使用我方的私钥
private-key对密文数据data进行数据解密,得到明文
接口请求
所有的请求和响应数据都需要进行加密解密加签验签。
以下是 http 协议的请求头 header 和请求体 body 的规范。
request header 键值
发起 http 请求时,需要在 header 中添加一组必要的键值:
X-Client:客户端标识 :机构编号(服务商编号)X-Security:安全模式 :固定赋值RSAX-Sign:签名 :数据密文的签名X-Time:请求时间 :当前世界标准时间的字符串,格式为RFC-1123标准。X-Trace:链路追踪号 :32位16进制小写的随机字符串,单位时间内不允许重复,正则 :^[0-9a-f]{32}$
request header 示例:
X-Client: 100000000000000000
X-Security: RSA
X-Sign: wxRoAeoPUvOUFedE9PMrPZVK9w083RAaypHQTKfcYU8MNLgFnEFuhsuxFWlXuiWUKahC835QimGym38fvx39bHxjHiNLmzDxKAfrw8YMpTAfZkkriQp4VTnxCtri5UI1H3J0kF/S8eW0EfxOGKkhGrUC092NvhuBqbgt3hDmWsg=
X-Time: Mon, 20 May 2024 09:50:41 GMT
X-Trace: 6266c110c07a4e79a17b98321ae9e801
request body 结构
请求的 body 是一个包含一个键值对的 json 对象,键固定为 param。值是一个 String 类型的密文字符串。
param:String 类型,密文字符串
一个接口的 param 通常为复杂的参数对象。
参数明文为参数对象的 json 格式的序列化的字符串。
参数密文为参数明文字符串的加密字符串。
request body 示例(明文):
{
"param": {
"name": "喵喵"
}
}
以上格式仅为示例接口的明文格式,实际传输时,需要将明文加密后,再传输。
request body 示例(密文):
{
"param": "Uu26Pg3ZOEz1BwLQ8NS7nvJ2IsH3qUj1W3Gc09WVYzLzlek/guAFssuErw4QpihbQJNnYCzAbkYCSIU3zlggdLsQ11oepesz07kH/XRTGambAXRCKMH7/OV9f4oHijli9rOyomT+/hHM7BNXdAG6dZKMaMrXWI8b3o4UAfrFI6Y="
}
如果参数对象为空(通常是在不需要传递具体的参数数据时),请传递空对象。
空对象的序列化后的字符串明文为 {} ,密文则为这个字符串 {} 的加密字符串
接口响应
接口的响应与请求类似,也需要进行加密解密加签验签。
以下是 http 协议的响应头 header 和响应体 body 的规范。
response header 键值
X-Client:客户端标识 :机构编号(服务商编号)X-Security:安全模式 :固定赋值RSAX-Sign:签名 :数据密文的签名X-Time:请求时间 :当前世界标准时间的字符串,格式为RFC-1123标准。X-Trace:链路追踪号 :32位16进制小写的随机字符串,单位时间内不允许重复,正则 :^[0-9a-f]{32}$
response header 示例:
X-Client: 100000000000000000
X-Security: RSA
X-Sign: d0cbRmr7yN7OBRePGH1WLnS8SMy8yHRhiyzcNmAd1H0aryhOp9rinLlRevsuuVd6k8uixKCOkLH6WP1TW/Z/vYb5k0euj0W38AoKbpG9+zpHo8KvL2kAZf0zQl2z/4cBn75QAJRDr4PdmJ1yn2avxdciXUfzpZDYxtCFOFzAb4k=
X-Time: Mon, 20 May 2024 09:51:45 GMT
X-Trace: a4b9a12fbee465d027dc72983ee39535
请注意 response header 中的 X-Trace ,在开发测试联调和排查生产问题时,应当首先尝试提供这个 链路追踪号 ,便于我司技术支持快速定位问题。
response body 结构
响应的 body 是一个包含至少三个键值对的 json 对象,键固定为 code , message 和 data。
code: 响应编码,数字字符串000000表示成功,其他表示异常message: 响应信息,字符串。如果发生异常,通常会展示具体的异常提示data: String 类型,密文字符串
一个接口的 data 通常为复杂的数据对象。
数据明文为数据对象的 json 格式的序列化的字符串。
数据密文为数据明文字符串的加密字符串。
response body 示例(明文):
{
"code": "000000",
"message": "OK",
"data": {
"name": "喵喵"
}
}
以上格式仅为示例接口的明文格式,实际响应时,则是将明文加密后,再返回。
response body 示例(密文):
{
"code": "000000",
"message": "OK",
"data": "JXfFmP5qhOCJQugpRWrHi8BSgVEtt0KlDGpzhiW1bhVzl0k8siD7jKKnIF/DcgWVloZKEs0MtE84ZtX+Altw8mg1Z/LHsJ0fbQjm/RctQxvj5ZbYGMqL6wXKOf1Wzjq/gg2WL3tJT6fcPY3EFluSDy1D8ynhlT10xu9z7ad1fN4="
}
如果数据对象为空(通常是在不需要返回具体的数据或者发生了异常时),则返回空对象。
空对象的序列化后的字符串明文为 {} ,密文则为这个字符串 {} 的加密字符串
代码示例
在文档的后续章节中,会提供一些主流的编程语言的代码示例,以便开发人员更好地理解和实现数据的加密解密加签验签。
如果需要更多其它语言 的代码示例,可以联系我司技术支持。
参考下一章节:Code-demo
RSA 算法不支持直接加解密长文本。 即 RSA 算法规定:
待加密的字节数不能超过密钥的长度值除以 8 再减去 11 。
待解密的字节数不能超过密钥的长度值除以 8 。
在实际应用中,需要对长文本进行分块处理。