【仅供内部供应商使用,不提供对外解答和培训】

Page tree

【仅供内部供应商使用,不提供对外解答和培训】

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

一、特殊名词介绍

参数解密:特指在访问决策系统资源时,传递的参数为加密数据的场景。

二、常用接口说明

参数解密又分为以下几种细分场景:

1、请求的整个query被加密的情况 —— eg): 原始URL webroot/decision?p1=v1&p2=v2&pn=vn  ;    加密后URL webroot/decision?crypt=code1  其中code1 就是 p1=v1&p2=v2&pn=vn 加密的密文

2、请求的query参数名、参数值分别被加密或仅参数值被加密 —— eg): 原始URL webroot/decision?p1=v1&p2=v2&pn=vn  ; 加密后URL webroot/decision?p1=code1&p2=code2&pn=coden

3、参数通过请求的body/header加密传输


实现参数的解密主要依赖于请求的拦截。最主要的接口就是GlobalRequestFilterProvider 和 RequestParameterHandler。二者都可以在一定条件下实现请求参数的解密,但各有缺陷。

其中GlobalRequestFilterProvider接口,可通过篡改请求信息的手段来实现,参数的解密。但是该接口不支持热部署,每次更新、安装、注册授权 均需要重启服务器才能保障有效。

RequestParameterHandler接口,本身是通过在产品封装的参数读取API内部,进行替换从而实现参数的解密,也就是该接口只能用于通过产品标准API读取参数的场景。类似body和header中的加密场景并不一定能使用。


而根据参数加密的具体实现位置,场景又分为:前端加密后端加密两种。

通常后端加密主要用于安全性较高的场景,相对的对服务器的消耗就较大一些。而前端加密由于加密过程可被前端直接较低成本就模拟实现一般用于安全性要求略低,但是加密并发算力要求较高的场景,减小服务端开销。


加密的方案按照加密使用的算法又分为:不可逆加密(校验类)和可逆加密

常见的不可逆加密(校验类)本质并不是对请求的参数进行加密,而是通过某种私钥对请求的参数进行签名(常见的 MD5\SHA256)。参数读取时,利用私钥校验参数和签名是否匹配来确保参数的有效。这类方案的重点不在于加密参数值,防止别人知晓参数的具体值。而是强调请求参数的不可篡改或者说访问资源的有效授权甚至预防请求重放

不可逆加密伪代码示例
//场景:以固定密钥进行MD5参数签名为例。现有业务系统服务器SA,和决策平台FR。
//在浏览器B上,通过登录SA访问FR的报表X,对其中的参数p1和p2进行防篡改保护

//准备:SA和FR后台约定一个固定且复杂度安全的密钥SCT, 假设不存在人为泄露密钥的可能。

//SA服务端生成校验信息:
func( Map parameters )
//parameters是原始报表的url的参数表信息
String query = sort(parameters);
//sort方法表示,将参数表按照双方约定的某种排序方法进行排序得到一个固定的参数名与参数值的键值对字符串
String SIGN = MD5( query + SCT + timestamp + timeout ) + timestamp + timeout
//其中timestamp表示生成签名的时间戳,timeout表示签名的有效期

//浏览器B实际访问的URL 为 url?query&sign=SIGN

//FR服务器在处理需要校验参数的请求获取具体参数时,先校验签名信息
//获取请求中的签名对象SIGN{ md5,timestamp, timeout}
SIGN sign = getSign(req);
//判断是否超时
if( isTimeout( sign.timestamp, sign.timeout, crtTimestamp ) ){
	//超时,返回一个参数空值/或者抛出异常
	return StringUtils.EMPTY;
}
//比较md5值是否一致
//此时的parameters需要排除sign参数
String query = sort(parameters);
if( sign.md5 != MD5(query + SCT + sign.timestamp + sign.timeout) ){
	//签名不匹配,返回一个参数空值/或者抛出异常
	return StringUtils.EMPTY;
}
//返回获取到的具体参数值
return value;


常见的可逆加密相应的,是对参数信息本身进行加密。密文可以通过可逆手段还原出原来的明文信息。它即可保障在密钥安全的前提下,请求不被篡改;也可以保障参数值本身不被肉眼或简单算法逆向识别。这类方案的重点则是保护参数中涉及的涉敏信息,诸如密码、身份证号、手机号、邮箱等等信息不轻易泄露。常见的可逆加密主要有 3DES、AES、RSA、HMAC等算法。

可逆加密伪代码示例
//场景:以固定密钥进行AES参数加密为例。现有业务系统服务器SA,和决策平台FR。
//在浏览器B上,通过登录SA访问FR的报表X,对其中的参数p1和p2进行加密保护(仅加密参数值)

//准备:SA和FR后台约定一个固定且复杂度安全的密钥SCT, 假设不存在人为泄露密钥的可能。

//SA服务端生成加密信息:
func( Map parameters )
for( Entry entry : parameters ){
	entry.setValue( AES_E( entry.getValue(), SCT ) );
}
String query = toQuery(parameters);

//浏览器B最终访问 url?query

//FR服务器在处理需要校验参数的请求获取具体参数时,进行参数解密
//获取请求中的参数密文
String value = req.getParameter(name);
//解密密文
return AES_D( value, SCT );


GlobalRequestFilterProviderRequestParameterHandler在一定条件下都可以实现上面的两种场景。


三、开源案例

免责声明:所有文档中的开源示例,均为开发者自行开发并提供。仅用于参考和学习使用,开发者和官方均无义务对开源案例所涉及的所有成果进行教学和指导。若作为商用一切后果责任由使用者自行承担。

视频课程配套demo

  • No labels