F5 API安全防护:SM2应用层解密/验签
2021-02-12 20:36:57
F5小安
F5 API安全防护:SM2应用层解密/验签
背景
随着API应用的广泛部署,中国人民银行发布了《商业银行应用程序接口安全管理规范》,规范提出对于A2级别接口,需要使用包含数字证书以及公私密钥对的方式进行双向认证,商业银行和应用方应使用数字签名来保证数据的完整性和不可抵赖性,相关账号/卡号/ 姓名/证件号等使用SDK中的加密组件进行加密,或者对报文进行整体加密处理。
根据上述规范的要求,API应用需要采用应用层加密的方式,对传输内容进行局部或者整体加密,并采用数字签名的方式对数据的完整和身份信息提供识别,在上述部署模式下,对企业的安全部门监管API应用形成挑战,企业IT安全部门无法识别API应用的传输内容,无法对API应用中可能存在的攻击风险进行抵御。
本文阐述如何通过F5 BIGIP,实现对应用层国密算法加密的内容进行解密,验签,同时对解密内容应用高级WAF防护功能,对API调用方提交的内容合法性/格式进行校验,同时不改变现有的API 服务器本身的解密机制,无缝和现有的API服务进行整合
部署架构
F5 BIGIP可以传输到API网关的报文保持原加密状态或传输解密后的报文,后端的API网关服务器可以工作在两种模式
1.沿用原来的模式,对应用数据进行验签,解密,根据验签结果获取用户信息,执行业务操作
2.API网关处理解密后的明文,此时F5 BIGIP将验签过程中获取到用户信息通过HTTP报文头的模式透传到API网关。
实施Demo方案
整体环境
Demo方案中包含
1.NodeJs编写的HTTP 发送SM2解密/签名内容客户端
2.F5 BIGIP V14.1
3.Nodejs服务器模拟API网关
预先生成SM2密钥对包含;
客户端公钥:04c3b87e0aa0643b448a9b5c51205821cb97809bd7e09c60c26700e8c8049c7e028158dc5b0678ec8a6ab757f41c378b36bf48c04f80314f3896c3c0a6f5c5260d
客户端私钥:dcef848d1d0f17cfaa69ee95f1ca1bd966daf50bb5b440ade898afe5d2ef2b86
服务器公钥:04054a549920b9e9f073352044f5db8665a04280a11a5f5bdfca683ae96967cbd5fdabf5d38aff1d2b90660225f066fec33462430e05b94f233da94f2cfbe882a3
服务器私钥:2642eb2d7a49c583884967cd6b26b8e795bf700ad0eaa14ba0167d713c25db26
客户端应用代码
客户端应用代码如下:
|
const sm2 = require('sm-crypto').sm2
|
该客户端主要功能为
1.将远程执行攻击报文插入JSON参数值,通过API网关的SM2公钥进行加密
2.将加密后的攻击报文通过客户端的私钥生成签名
3.将客户端的用户信息以及报文签名信息写入报文头Content_Sig和Auth字段,发送数据到F5 BIGIP
F5 BIGIP配置
以下配置为保持加密内容传送到API网关的设置,如需要传输解密报文,可以对iRule进行简单的修改即可。
首先F5 BIGIP使用iRuleLX,安装开源SM2库,通过iRuleLX对报文进行验签解密,需要在F5 BIGIP上存储客户端公钥,API服务器私钥,同时开启AWAF防护功能,对加密的攻击报文进行拦截。
iRuleLX需要使用npm下载国密SM算法的动态库,需要运行下面的命令:
cd /var/ilx/workspaces/<partition_name>/<workspace_name>/extensions/<extension_name>/
npm install sm-crypto
可以完成后可以在iRuleLX中执行SM2,SM3,SM4算法
iRule LX的iRule部分如下:
|
when HTTP_REQUEST { if {[HTTP::method] eq "POST"}{ if {[HTTP::header "Content-Length"] ne "" && [HTTP::header "Content-Length"] <= 1048576}{ set content_length [HTTP::header "Content-Length"] } else { set content_length 1048576 } if { $content_length > 0} { HTTP::collect $content_length set sig [HTTP::header "Content_Sig"] set clientuser [HTTP::header "Auth"] set clientpubkey [class match -value $clientuser equals clientPlubicKey ] } } } when HTTP_REQUEST_DATA { set payload [HTTP::payload]
set ilx_handle [ILX::init "pluging_sm2" "PayLoad_SM2"] if {[catch {ILX::call $ilx_handle "decryptsm2" $clientpubkey $payload $sig } result]} { log local0.error "Client - [IP::client_addr], ILX failure: $result" return } set verifyResult [ lindex $result 0] set decryptPayLoad [ lindex $result 1] HTTP::payload replace 0 $content_length $decryptPayLoad HTTP::release } when ASM_REQUEST_DONE {
ASM::payload replace 0 [string length $decryptPayLoad] $payload HTTP::header replace Content-Length [ASM::payload length] }
|
NodeJS部分如下:
|
var f5 = require('f5-nodejs'); var ilx = new f5.ILXServer();
ilx.addMethod('decryptsm2', function (req, res) {
var clientpublicKey = req.params()[0]; var payload = req.params()[1]; var sigValue = req.params()[2]; console.log('payload is '+payload); console.log('sig is '+sigValue); console.log('client public key is '+clientpublicKey);
try { var sm2 = require('sm-crypto').sm2 var verifyResult = sm2.doVerifySignature(payload, sigValue, clientpublicKey) console.log('the sig verify result is '+ verifyResult); var serverPrivateKey ='2642eb2d7a49c583884967cd6b26b8e795bf700ad0eaa14ba0167d713c25db26' var decryptPayload = sm2.doDecrypt(payload, serverPrivateKey, 1) console.log('decryptPayload is '+ decryptPayload)
if(verifyResult) { res.reply([true,decryptPayload]); }else{ res.reply([false,null]) } } catch (e) { console.error('Error with:', e.message); console.error('Stack trace:', e.stack); return; } }); ilx.listen(); |
其中:
serverPrivateKey为API网关私钥
DataGroup配置为用户名/公钥 kv,如下:
|
ltm data-group internal /Common/clientPlubicKey { records { testuser { data 04c3b87e0aa0643b448a9b5c51205821cb97809bd7e09c60c26700e8c8049c7e028158dc5b0678ec8a6ab757f41c378b36bf48c04f80314f3896c3c0a6f5c5260d } } type string } |
本例中,pluging_sm2作为pluging名称, PayLoad_SM2为extention名称
此后,配置F5 BIGIP上的应用安全策略,同时将API安全策略,SM2验签/解密的iRuleLx应用到关联的API网关VS即可。
服务器端只做简单的屏幕回写payload:
|
var http = require('http'); http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'}); res.write('cmbchina 8081\r\n\r\n'); res.end(); req.on('data',(data) => { console.log("Server get Data") console.log(data.toString());
}) }).listen(8080, '0.0.0.0');
console.log('Server running at 8080/'); |
效果验证
完成上述配置后,运行客户端应用可以看到如下的截图反馈:
此时发送的加密报文为:
41e07940c6a829425671b99d3635c60f95d71201544be2cbfc120c6b14b65418bd3f60b4bc49a6552a345ac2ee7b217e32158a33ea3f4e239a848bb49f742dfb7ab1bb82880dfc5cb37de952bee2ed135dc55d273d8da4c9b8eae0a90b9d01e67602015f484599b57d092df71615a75c36daeb66afb420468a52cb4b0a36d4dc1496bd08712a993de9a601a7f157d7c0e2150b87b2bd4a2e1f39dfadfa36857198a356e57ac35320d2152a6f90031a288d4d116b5e
通过获取到的Support ID进行WAF攻击事件检索,可以看到具体的攻击内容如下:
如在客户端将发送报文修改为正常报文,不带任何攻击数据,可以在后端服务看到接受报文和客户端发送报文一致
小结
通过对应用层国密算法内容加密/验签的实现,F5 BIGIP将WAF功能真正应用到API这一新兴服务形态中,有效解决企业安全部门对API服务进行安全控制的痛点,提供API请求安全验证,格式验证,熔断限速,DDOS防护,身份信息识别,防止数据泄漏,进一步提升API服务的安全性和有效性,保障企业随着API经济的起飞稳步发展。
发布评论 加入社群
相关文章
回复评论
发布评论