邱 帆 胡凯雨 左黎明 张梦丽
1(国网江西省电力公司吉安电力科学研究院 江西 吉安 343000)2(华东交通大学系统工程与密码学研究所 江西 南昌 330013)
随着网络通信技术的不断发展和完善,信息通信技术也逐渐运用于配电网之中形成配电网的信息物理系统,而配电网分布式控制是一种基于智能终端测控信息对等交换的控制技术,可以利用多个站点的测量信息提高保护控制性能,同时改善主站集中控制响应速度,是实现配电网信息物理系统的关键支撑技术。然而由于智能终端分布在各个地区,且装置数据存储与传输能力等较差,非常容易受到黑客的攻击。2008年,美国中央情报局称在美国境外发生数起黑客通过互联网攻破当地供电网络导致数个城市出现照明中断事件[1]。2015年12月,俄罗斯黑客组织通过电网安全漏洞获取远程控制权限,并关闭了数十个断路器,造成数万户家庭停电[2]。2017年在美国、土耳其和瑞士发生多起黑客攻击电网以获取电网运营控制面板事件[3]。
因此,对分布式控制技术的研究需要从电网的安全防护角度考虑,在实现分布式控制的同时保证电网系统的安全性。而系统安全性的重要指标是要对数据来源的身份进行认证。但对于身份认证的协议国内外相关机构并没有形成国际标准。因此,国内外专家学者就电网中通信身份认证技术进行研究。1979年,LAMPORT[4]提出了一次性签名算法的最初架构。2012年,郭非等[5]设计一种基于身份的智能电网认证模式,但该模式只考虑到移动端的用户身份认证问题。2013年,王爽等[6]对身份认证和访问控制技术在智能电网中的应用进行讨论,但并没有提出具体的安全方案。2018年,李玉等[7]对电网核心业务可信身份认证框架体系研究,但仅仅是理论上的研究并没有运用到实际的电网项目中。2018年,卢昕等[8]对面向配电网分布式控制的身份认证技术进行了研究,提出一次性签名的轻量级身份认证算法,但其签名方案并没有严格的可证明安全,因此可能存在安全性问题。
本文对配电网分布式控制原理进行研究,并结合国密SM9签名算法[9],设计基于SM9的配电网分布式控制的身份认证技术,并在国电南瑞生产的PDZ810-FTU智能配电终端上对签名算法的计算效率进行实验,结果表明签名安全性较好,且效率较高,能有效地在实现分布式控制的同时保证电网系统的安全性。
由于本文仅针对配电网分布式控制的安全性进行研究,因此对攻击者模型设计如下:
(1) 假定密钥生成中心是安全可靠的,攻击者来自恶意的用户;
(2) 攻击者主要针对的是计算、数据存储与传输能力等较差的智能终端;
(3) 密钥生成中心存储所有智能终端的身份ID,且可根据编号生成密钥对,也可对数据进行认证和处理。因此,攻击者进行密钥替换攻击概率较小。
配电网分布式控制身份认证工作框架如图1所示,该框架架构分为密钥管理模块和身份认证模块,其中身份认证用于对签名进行验证以保证信息的完整性,密钥管理模块主要是由密钥生成中心和身份编号更新模块组成,其中身份编号更新模块主要是将每日的时间和智能采集终端编号组成一个新的身份编号。
图1 配电网分布式控制身份认证工作框架
密钥生成中心根据生成的编号得出新的密钥对。其中,编号为IDi智能采集终端会被分配对应的私钥,在产生需要签名的报文信息Message后,智能采集终端IDi根据私钥对Message进行签名,并将Message和签名通过组播的方式发送到局域网。而其他智能采集终端IDj订阅了来自智能采集终端IDi的信息可根据公布的公钥对签名进行验证。
本文提出的身份认证工作框架的安全性是建立在基于椭圆曲线[10]密码(Elliptic Curve Cryptography,ECC)机制的SM9签名算法上,且框架中的密钥管理模块中的身份编号更新模块时间戳机制使生成的密钥对每次都不同,因此生成的签名消息也不同,有效地避免了一些恶意重放攻击。在不考虑攻击者攻击密钥生成以获取密钥的情况下,攻击者在密钥有效期之内无法通过人为猜解或挂字典的形式暴力破解出密钥。
1984年,Shamir[11]首次提出了基于身份的密码体制(Identity-Based Cryptography,IBC),用户的公钥可以与用户的手机号码、身份证号码等关联,省略了交换数字证书和公钥过程,有效地减轻了签名者对证书的依赖性,提高了密钥管理的效率。2008年,程朝辉等将IBC技术进行标准化,形成了我国商用密码算法SM9。其中SM9签名算法由系统初始化(Setup)、密钥生成算法(KeyEx)、签名生成算法和签名验证算法(Verify)四个多项式时间算法组成。
3) 签名生成算法(Sign):对待签名的消息M,签名者可通过以下运算步骤实现消息M的数字签名(h,S):
(1) 计算g=e(P1,Ppub);
(2) 令r∈[1,N-1],计算ω=gr,h=H2(M‖ω,N);
(3) 计算L=(r-h)modN,若L=0则返回(2);
(4) 计算S=Ld,则消息M的签名为(h,S)。
4) 签名验证算法(Verify):对于接收到的消息M′及其数字签名(h′,S′),验证者可通过运算步骤进行签名验证:
(1) 检验h′∈[1,N-1]与S′∈G1是否成立,若不成立则验证不通过;
(2) 令g=e(P1,Ppub),计算t=gh′,h1=H1(IDA‖hid,N),P=h1P2+Ppub;
(3) 计算μ=e(S′,P),ω′=μ·t,h2=H2(M′‖ω′,N);
(4) 检验h2=h′是否成立,若成立则验证通过否则验证不通过。
上述SM9签名算法具体参数定义与计算过程参考文献[9]。针对身份认证框架而言,对于框架中的密钥更新,每个智能采集终端IDi和每日的时间组成新的编号运行密钥生成算法(KeyEx)生成一个全新的密钥对,运行签名生成算法(Sign)对不同消息进行签名。身份认证模块只需要根据更新后的公钥运行签名验证算法(Verify)对发送过来的签名进行验证。
框架模块设计对于每个智能终端主要由数据处理模块、签名模块、通信模块和签名验证模块组成。智能终端间的通信以封包格式传输,数据处理模块主要用于将消息进行哈希运算,进一步封装为封包和将封包进行拆包取出包内消息;签名模块主要用于智能终端内的唯一私钥对封包消息进行签名;通信模块用于独立的智能终端间的通信,即发送和接收封包;签名验证模块用于对收到的签名进行签名验证,以保证数据未被篡改和数据的完整性。框架模块设计如图2所示。
图2 框架模块设计
电流数据采集到数据监控平台的数据交互流程如图3所示,包括以下步骤:
(1) 每天凌晨时分,身份编号更新模块将每日的时间和智能采集终端编号组成一个新的身份编号。并将编号发送给密钥生成中心。密钥生成中心根据密钥生成算法生成密钥对,并根据编号分发给每个智能终端。
(2) 智能终端ID对需要发送的指令Message、对应编号ID和时间戳T进行哈希运算Hash(ID#Message#T),签名模块根据分发好的密钥对计算后哈希值进行签名Sign(Hash(ID#Message#T))签名完成后,通过数据处理模块组成形如ID#Message#T#Sign(Hash(ID#Message#T))封包后发送。
(3) 其他智能采集终端订阅了来自智能采集终端ID的信息可根据连接符对封包进行解析,并对签名数据进行验证。如果签名验证失败,则通知智能采集终端不进行任何操作。否则,智能终端接受数据,并执行操作。
图3 智能终端安全交互流程
实验环境为电脑中央处理器Intel i5 7200U,内存海盗船DDR4 16 GB,Windows 10 64位操作系统,通过微软提供的Visual Studio 2012开发平台利用C++实现SM9签名算法,通过对不同长度的信息进行30次签名得出如表1所示方案在签名和签名验证阶段的平均耗时。其中Lm表示以Byte为单位的信息长度、tsign表示签名平均耗时、tverify表示签名验证平均耗时。
由表1可知,签名信息长度越长,签名和签名验证所消耗的时间越长。但签名到达一定长度时,签名和验证消耗的时间达到平衡,其原因在于Hash函数会将消息长度分成多个长度一致的数据块,用于处理对应消息摘要。而由于密钥的长度是固定不变的,因此在进行Hash运算的时候不受长度影响。
表1 报文长度不同时签名的耗时(仿真)
为了模拟真实环境,在国电南瑞生产的PDZ810-FTU智能配电终端(硬件:高端32嵌入式RISC CPU,软件平台嵌入式操作系统:Linux 2.6版uClinux)上结合C语言环境下椭圆曲线上的双线性对运算和PBC库实现了签名算法,并通过对不同长度的信息进行30次签名得出如表2所示方案在签名和签名验证阶段的平均耗时。其中Lm表示以Byte为单位的信息长度、t表示从签名到签名验证的平均耗时。
表2 报文长度不同时签名的耗时(实验)
由表2可知,当传送数据长度为512 Byte时,方案从签名到签名验证的时间为1.721 ms,然而值得注意的是,在签名消息Message的基础上需要加入一定长度的签名,因此总的传输时间为2.23 ms。同时在此环境下还模拟了恶意攻击者对智能终端进行攻击,而基于SM9签名的身份认证算法对恶意攻击者发送的消息进行认证,发现身份认证失败,得出发送方是没有权限的恶意用户,且根据发送消息中的编号可快速定位被攻击的智能终端,并及时采取防御措施。
系统各阶段关键核心代码叙述如下:
(1) 系统初始化参数阶段。首先定义pairing_t类型的双线性对pairing,然后定义element_t类型的参数变量,最后分别使用element_init_G1函数初始化群G1上的元素,使用element_init_Zr函数初始化群Zr上的元素和使用element_init_GT函数初始化群GT上的元素,具体代码如下:
pairing_t pairing;
element_t P1, e,N;
//系统参数
element_t s,P_pub;
//系统密钥
element_t d,Q;
//用户私钥,公钥
element_t hid;
//识别符
//生成用户公私钥的中间变量
element_t t1,t2,h_temp,t1_invert,Q_temp;
element_t r,w,L;
//生成签名的中间变量
element_t h,Sig;
//签名
//验证签名的中间变量
element_t g,w_pie,u,h1,h2,t,P,P_temp;
if (pairing_init_set_buf(pairing, eparam, strlen(eparam))) printf(″pairing init failed″);
element_init_G1(e, pairing);
//群G
element_init_Zr(N, pairing);
//系统密钥
element_init_G1(d, pairing);
//群G用户私钥
element_init_G1(Q, pairing);
//群G用户公钥
element_init_Zr(hid, pairing);
//识别符
//生成用户公私钥的中间变量
element_init_Zr(t1, pairing);
//生成用户公私钥的中间变量
element_init_Zr(t2, pairing)
element_random(N);
element_random(hid);
(2) 系统密钥的生成。首先初始化系统公钥相关参数,然后利用element_random设定系统主密钥s的值,最后使用element_mul函数计算系统公钥的生成。
/*******系统公钥生成**********/
element_init_Zr(s, pairing);
//系统密钥
element_init_G1(P_pub, pairing);
//系统公钥
element_init_G1(P1, pairing);
//群G的生成元
element_random(P1);
element_random(s);
element_mul(P_pub,s,P1);
//计算P_pub=s*P2
(3) 生成用户公私钥。首先初始化用户密钥生成相关参数,并利用strcat函数拼接用户ID、识别符和N,然后利用element_from_hash函数对拼接字符数组进行hash运算,最后利用element_add相加函数、element_invert求逆函数和element_mul相乘函数求得用户的私钥d和用户公钥Q。
element_init_Zr(t1_invert, pairing);
element_init_Zr(h_temp, pairing);
element_init_G1(Q_temp, pairing);
char ID[30] = ″zmlzmlzml″;
strcat(IDhN,ID);
//hid ,ID
strcat(IDhN,N);
//hid,N
element_from_hash(h_temp, IDhN,strlen(IDhN));
//h_temp=H1(ID||hid,N)
element_add(t1,h_temp,s);
//t1=H1(ID||hid,N)+s
element_invert(t1_invert,t1);
//(t1)^(-1)
element_mul(t2,s,t1_invert);
//计算t1=s*t1_invert
//计算用户私钥
element_mul(d,t2,P1);
//计算d=t2*P1
//计算用户公钥 Q=H1(ID‖hid,N)*P1+P_pub
element_mul(Q_temp,h_temp,P1);
//计算Q_temp=H1(ID‖hid,N)*P1
element_add(Q,Q_temp,P_pub);
(4) 生成签名阶段。首先初始化生成签名相关参数,然后使用element_pairing双线性对运算函数计算g=e(P1,Ppub),使用element_pow_zn函数计算ω=gr,使用element_from_hash哈希函数求哈希值h,使用element_sub函数计算L=(r-h)modN,最后使用element_mul函数计算签名S=Ld。代码如下:
element_init_GT(g, pairing);
//g为GT的元素
element_init_Zr(r, pairing);
//r为Zr上的元素
element_init_GT(w, pairing);
element_init_GT(w_pie, pairing);
element_init_Zr(h, pairing);
element_init_Zr(L, pairing);
//L为Zr上的元素
element_init_G1(Sig, pairing);
element_random(r);
char m[30] = ″messege″;
element_pairing(g, P1, P_pub);
element_pow_zn(w,g,r);
element_from_hash(h, mwn,strlen(mwn));
//h_temp=H1(M‖w,N)
element_sub(L,r,h);
element_mul(Sig,L,d);
(5) 签名验证阶段。首先初始化签名验证相关参数,然后分别计算出t、h1和P。使用element_pairing函数、element_mul函数和element_from_hash函数依次计算出μ=e(S′,P)、ω′=μ·t和h2=H2(M′‖ω′,N);最后使用element_cmp比较函数验证h2与h′是否相等,即签名验证是否成功。
element_init_GT(t, pairing);
//gt为GT的元素
element_init_Zr(h1, pairing);
element_init_G1(P, pairing);
element_init_GT(u, pairing);
//gt为GT的元素
element_init_GT(w, pairing);
//gt为GT的元素
element_init_Zr(h2, pairing);
element_init_G1(P_temp, pairing);
element_pow_zn(t,g,r);
element_mul(P_temp,h1,P1);
element_add(P,P_temp,P_pub);
element_pairing(u, Sig, P);
element_mul(w_pie,u,t);
element_from_hash(h2, mwn_pie, strlen(mwn_pie));
//h_temp=H1(M‖w,N)
if (!element_cmp(h2, h)) {
printf(″签名验证失败! ″);
}
else
{
printf(″签名验证成功! ″);
}
最后程序运行签名结果如图4所示,可以看出程序运行时间为117 ms,证明本文方案具有高效性。
图4 签名运行结果
本文设计基于SM9的配电网分布式控制的身份认证技术方案,能有效地实现分布式控制的同时保证电网系统的安全性。本文首先介绍了总体框架的设计,并分析了框架的安全性,随后详细叙述了SM9签名算法,最后通过在国电南瑞生产的PDZ810-FTU智能配电终端实现签名算法,并通过长时间运行测试,期间并未出现运行不稳定以及相关安全问题,证实方案具有较高的稳定性和实用性,并且方案基于国密SM9签名算法,具有较强的安全性。今后,配电网分布式控制对数据交互的安全性和性能会有更高的要求,而本文仅采用国密算法对数据进行安全性认证,因此,下一步工作将研究高效安全的密码学方案并运用于配电网分布式控制。