linux 下 c++ 实现 netstat_Linux下基于签名技术的软件保护之实现流程
2.1 软件总体流程
在信息安全中,安全通信需要具有以下三个特性[8]。①机密性,仅有发送者和接受者能够理解传送信息的含义,保证信息在传输时不被泄露。②完整性,需要确保信息在传输过程中不被篡改。③有效性,也称端点鉴别,即发送方和接收方都能证实通信的另一方确实具有他们声称的身份,确保信息的使用者时合法的。为了使开发的软件保护程序满足安全通信的三要素,利用公私钥密码来解决机密性,利用数字签名解决完整性和有效性问题,完成了基于证书的签名和认证程序。
2.1.1 基于证书的签名程序
对于Linux下给定的ELF可执行程序进行签名,主要包括以下四个步骤,如图2-1所示。
(1)使用SM3国密算法对程序的代码段(Load Segment)进行散列,用私钥对散列值进行加密,得到“数字签名”,得到的签名数据作为单独的节(Section)附加到ELF可执行文件的尾部。
(2)将解密所需要的开发者公钥作为单独的节附加到ELF可执行文件的尾部。这样就可以通过公钥对(1)中得到的数字签名进行解密,得到哈希值,若得到的哈希值与原ELF代码段的哈希值相同,则验证通过。
(3)为了确保ELF文件中附加的公钥的真实性,需要UOS官方认证中心对公钥进行认证,并将得到的认证证书附加到ELF文件的尾部。以此确保信息的有效性。
(4)最后需要附加4B长度的单独节用以标识公钥的真实长度。
2.1.2 基于证书的验证程序
在ELF文件运行之前,需要对文件进行验证。若ELF可执行程序没有被签名或者签名验证失败则应停止运行本程序,若签名验证成功则可以正常运行。根据在签名过程中附加的节,可以很自然得到基于证书的验证程序,主要包括以下步骤,如图2-2所示。
(1)根据附加的节Section,得到开发者公钥的长度, 并从ELF文件中读取开发者公钥。接着使用SM3国密算法,对公钥进行散列得到散列值。
(2)读取ELF文件中的存放公钥认证文件的值,使用UOS认证中心的公钥对其进行解密,得到公钥的散列值,并于(1)中得到的公钥散列值进行对比,若相同则证明公钥是真实有效的,否则验证失败,程序停止运行。
(3)读取附加在ELF文件中的签名数据,并用(2)中经过验证的公钥对其进行解密,得到解密后的ELF文件代码段的散列值。
(4)对ELF文件中的代码段(Load Segment)通过SM3国密算法计算其散列值,并与(3)中得到的散列值进行对比。若散列值相同则证实了ELF文件的安全性和可靠性,验证通过,执行ELF文件;否则验证失败,中断ELF文件的执行。
2.2 内置UOS公钥与内核钩子程序
为了保证内核代码不被修改,同时也为了维护测试的方便性,开发外置内核模块,挂钩Linux内核的进程启动流程作为ELF签名文件的验证程序。开发钩子函数,挂钩住ELF的执行入口函数“load_elf_binary”,并在外置的钩子中实现ELF认证签名文件、公钥、证书的读取及验证工作。验证通过则返回原入口函数处继续运行ELF文件,否则停止运行该ELF文件。
2.2.1 钩子的定义
钩子[9]表示一个允许编程者插入自定义程序的地方,通常是打包好的程序中提供的接口。通过钩子,可以实现暂停系统调用,或通过改变系统调用的参数来改变正常的输出结果,甚至可以终止一个当前运行的进程并将控制权转移到程序员的手中。钩子执行示意图如图2-3所示。
钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有达到目标窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时候钩子函数即可以加工处理(改变)该消息,也可以不做处理而继续传递该消息,还可以强制结束消息的传递。
2.2.2 内核中钩子原理分析
在未加入钩子前调用函数X的流程,如图2-4 a)所示。当执行到调用函数X的指令时,根据函数在内存中的入口地址进行相应的跳转,执行完毕后再返回原跳转处继续执行下一个指令。
加入钩子后调用函数X的执行流程,如图2-4 b)所示。其中STUB.hook为框架自定以的函数模板,并跳转到hook.fn函数,如步骤(3)所示。hook.fn是使用者自定义的函数,在Linux下基于签名技术的软件保护的实现中,该函数被定义为“khook_load_elf_binary”。以此来实现不修改内核源码,开发外置内核模块挂钩Linux内核的进程启动流程作为验证程序。
一般来说,自定义的钩子函数最后也会调用框架自定的钩子原函数,即http://STUB.org。如图步骤(4)用来保证正常的执行流程不会出错。由于函数X的第一条指令被替换成了JUMP跳转指令,为了正常执行函数X,则需要先回到X然后执行被替换掉的内容,如图步骤(5)。总的来说,对于需要钩子钩住的函数,用JUMP跳转指令替换其前几个字节。这样当执行函数X时会跳转到框架自定义的STUB代码部分,STUB再调用用户自定义的钩子函数,如“khook_load_elf_binary”。接着会执行被钩住函数中被跳转指令所覆盖的执行,最后回到被钩住函数的正常执行逻辑。
2.2.3 内核钩子程序
在第一章中分析了ELF文件的执行流程,其中ELF中的加载程序为load_elf_binary。为了保证不修改内核源码,需要开发外置内核模块挂钩Linux内核的进程启动流程作为验证程序。因此钩子需要钩住load_elf_binary函数。通过挂钩,实现在调用ELF可执行文件之前,对ELF文件进行签名及验证。
在内核中有两种函数。一种是在内核中已经定义了函数声明的函数,另一中是在内核中未声明的,只是.c内部使用的函数。load_elf_binary属于第二种类型的函数。因此需要如下的方式进行钩子函数的定义。
- #include <linux/binfmts.h> // has no load_elf_binary() proto
- KHOOK_EXT(int, load_elf_binary, struct linux_binprm *);
- static int khook_load_elf_binary(struct linux_binprm *bprm)
- {
- int ret = 0;
- ret = KHOOK_ORIGIN(load_elf_binary, bprm);
- return ret;
- }
通过上述函数,就得到了用于钩住load_elf_binary函数的自定义的钩子函数(其它前期操作不做赘述)。在此钩子函数中需要完成ELF可执行文件加载之前的签名和验证工作,包括读取开发者公钥、读取ELF认证文件、验证开发者公钥、验证ELF认证文件等,流程如图2-5所示(流程图中只是展示函数运行的主要过程,并不是函数执行的具体过程,即并没有表明当读取或验证失败后的流程)。
如图2-5,当系统调用ELF文件时,钩子函数会首先被执行,即khook_load_elf_binary函数先获得控制权。在钩子函数中实现读取开发者公钥认证文件、开发者公钥、ELF认证文件并验证开发者公钥、ELF文件的功能。钩子函数执行完后,跳转到load_elf_binary函数,继续执行原函数的正常逻辑。这样就实现了在不修改内核源码的前提下,开发外置内核模块挂钩ELF的执行函数“load_elf_binary”,并在钩子函数中实现ELF可执行签名文件的验证功能。
2.3 UOS签发证书给开发者
2.3.1 公钥证书
在基于公私钥的签名认证程序中,签名过程是将ELF代码段的散列值经过私钥加密后得到“数据签名”附加到原ELF文件中,验证过程是用提供的公钥对“数据签名”进行解密得到加密前的散列值,同时将ELF代码段进行SM3国密算法散列,将这两个散列值进行对比,以此来验证ELF的完整性,如图2-6所示。复杂的情况出现了,当有第三方伪造公钥和私钥,将“假”公钥发送给原接收方,并用自己的私钥做成“数字签名”附在原信息上进行发送时。接收方会使用“假”公钥进行解密,并能够验证通过第三方不合法的ELF文件。由此可见基于公私钥的签名认证程序是存在缺陷的,也就是无法确保公钥的合法性。
要使公钥密码有用,就要能够证实通信的另一方确实具有他们声称的身份。为了验证公钥的合法性,就要涉及到数字签名的另一个重要的应用“公钥认证”,即证实公钥属于某个特定的实体。将公钥于特定的实体绑定通常是由认证中心完成的,CA的职责就是使识别和发行证书合法性。
2.3.2 公钥证书实现
在UOS系统下实现基于签名技术的软件保护程序,这里的验证中心即为UOS官方的认证中心。为了确保证书在传输过程中不被篡改,首先对开发者公钥进行SM3国密算法计算其散列值,再利用认证中心的私钥进行加密,得到公钥的认证证书,如图2-7所示。
公钥的认证证书与公钥均会作为单独的节附加在ELF文件的末尾。在执行ELF文件之前,会读取ELF文件的相关节,得到开发者的公钥及公钥的认证文件。利用UOS认证中心的私钥解密公钥的认证文件,可以得到加密前的散列值。同时,利用SM3国密算法对公钥进行散列,计算其散列值。如果得到的这两个散列值相同,就可以得到合法的真实的开发者公钥了。
2.4 开发者验证部分附加到ELF
签名和验证程序对ELF的代码段(Load Segment)首先进行散列,然后对散列值进行签名,签名数据应作为单独的节(Section)附加到原ELF可执行程序的尾部。同时为了实现基于证书的签名和认证程序,还需将经过UOS认证中心认证的公钥认证文件及公钥附加到ELF文件的尾部,与此同时,为了能够从ELF文件中准确读出公钥所在的节,需要将公钥长度的值作为另一个节附加到文件末尾。至此,可以得到在签名过程中,需要在ELF文件中额外添加的节。
通过对ELF文件进行加密后,得到的文件格式如图2-8所示。在原ELF可执行文件的结尾一共追加了四个单独的节(Section)。
第一部分,是用于存放ELF文件的认证数据的节。首先将ELF文件经过SM3国密算法进行散列后,得到32B的散列数据。在使用软件发布者的私钥进行RSA2014加密,加密后生成长度为2048bit的密文。最后将2048bit即256B的密文作为独立的节追加到ELF文件上。
第二部分,是用于存放软件开发者的公钥的节。开发者需要公钥作为独立的节(section)追加到ELF文件,用于软件的认证。该节的长度需要通过增添额外的节进行说明。
第三部分,是用于存放软件开发者公钥的认证文件的节。首先利用SM3国密算法将开发者的公钥进行散列,得到32B的公钥指纹。接着经过UOS官方审核并签发得到大小256B的开发者公钥认证证书。最后将UOS认证的证书作为单独的节追加到ELF文件。
第四部分,用于存放软件开发者公钥的长度。由于开发者公钥的长度不会超出2^32,所以可以用int类型的存放。最后将此部分作为单独的节追加到ELF文件中。
2.5 用户使用ELF文件
开发基于证书的验证软件并加入操作系统,在运行任何ELF可执行程序前对ELF文件进行验证,若ELF可执行程序没有被签名或者签名验证失败则应停止运行本程序,若签名验证成功则可以正常运行。
在用户使用ELF文件之前,需要对ELF文件进行验证。验证程序是由外置的内核钩子完成的,确保不修改内核代码,运行ELF可执行程序的方式保持不变。根据加密的过程,可以很自然得到验证签名的过程。签名与加密过程如图2-9所示。四个部分均作为单独的节附加在ELF文件的末尾,因此可以根据文件格式分别读取出ELF源文件、开发者公钥、数字签名验证这三个部分。
首先,需要验证附加在ELF文件中开发者公钥的合法性。利用UOS认证中心的私钥解密认证文件,得到开发者公钥的散列值。并对读取得到的开发者公钥进行SM3国密算法散列,将两个散列值进行对比,若相等,则证实了附加在ELF文件中公钥的合法性。
接着读取附加在ELF文件中的签名认证部分,利用合法的公钥对其进行解密,得到ELF文件中代码段的散列值。
最后读取ELF文件中的代码段,并求其散列值,再将这两个散列值进行对比,若相等,则该ELF文件认证通过,并执行该认证文件;否则,认证不通过,中断该ELF文件的执行。
linux 下 c++ 实现 netstat_Linux下基于签名技术的软件保护之实现流程相关推荐
- hadoop下计算机网络安全设计与实现,基于PKI技术的网络安全平台设计研究
科技信息 0 IT技术论坛0 SCIENCE&TECHNOLOGY INFORMATION 2008年 第4期 基于 PKI技术的网络安全平台设计研究 马 (陕西交通职业技术学院 骞 陕西 西 ...
- web html5音乐播放器设计与实现,基于HTML5技术的音乐播放器的设计与实现
Vol.33No.11Nov.2017 赤峰学院学报(自然科学版) Journal of Chifeng University (Natural Science Edition )第33卷第11期(下 ...
- 基于html的音乐播放设计,基于HTML5技术的音乐播放器的设计与实现
Vol.33No.11 Nov.2017 赤峰学院学报(自然科学版) JournalofChifengUniversity(NaturalScienceEdition) 第 33 卷第11 期(下) ...
- 一个Linux下的 俄罗斯方块游戏,基于 ncurse 库。。
2019独角兽企业重金招聘Python工程师标准>>> 几天前写得一个Linux下的 Tetris 游戏,基于 ncurses 库.. 望大家多多指教,功力太浅,多提代码的改进意见 ...
- linux环境用opencv读取图片,基于Linux下OpenCV的人脸识别模块设计
金笑雪 张琳琳 高丹 张黎 摘 要: 近年来,图像识别技术正在向更加直观.可靠的方向发展,其中人脸识别技术具有极高的研究价值,应用得也最为广泛.通过对Linux系统下OpenCV的研究,利用OpenC ...
- linux下开发教务管理系统c,基于Linux/NC中小学的资源管理和互动教学系统
1 引 言本文引用地址:http://www.eepw.com.cn/article/90252.htm Linux最早是由芬兰大学生Linus Torvalds于1991年开发的,其借鉴Unix系统 ...
- linux secure boot(安全启动)下为内核模块签名
文章目录 linux secure boot(安全启动)下为内核模块签名 背景 Secure Boot安全启动开启关闭方法 内核驱动签名 生成签名证书和私钥 导入签名证书 BIOS(UEFI)导入证书 ...
- Linux下配置Apache虚拟主机(基于IP地址)
Linux下配置Apache虚拟主机(基于IP地址) 一.虚拟主机 虚拟主机,又称虚拟服务器,是一种在单一主机或主机群上,实现多网域服务的方法,可以运行多个网站或服务的技术.虚拟主机之间完全独立,并可 ...
- linux安装基于PHP的web软件,Linux下Web服务器应用之基于LAMP构建phpwind论坛
Linux下Web服务器应用之 基于LAMP构建phpwind论坛 v什么是LAMP Ü目前最为成熟的一种企业网站应用模式,可提供动态Web站点应用及开发环境 v构成组件 ÜLinux.Apache. ...
最新文章
- H264 NALU 使用PS封装 RTP发送
- 在企业环境中部署 Microsoft Windows 恶意软件删除工具
- IT兄弟连 Java语法教程 Java的发展历程
- 如何判断京东达人文章是否下线
- 计算机管理内默认共享,关于Windows的默认共享介绍
- 如何用报表解决销售工作衡量问题
- java中的URLConnection
- 如何禁用Web表单字段/输入标签上的浏览器自动完成功能?
- 学术论文写作的 paper、code 资源
- java基础之static
- 思科CCNA考试流程-ielab
- 超神四年的王者荣耀 会被英雄联盟手游顺利推塔吗?
- java scjp 试题_SCJP(JAVA)试题一套!求答案...
- 通过split命令分割大文件
- docer-compose
- 我赢助手:视频不清晰很模糊,和原片差别很大该怎么办?作品零播放是怎么回事?
- Tomcat 运行 maven项目报错 com.sun.faces.config.ConfigureListener
- 天猫店群起店新玩法,安全稳定,天猫店群全店动销退款单后的玩法
- 500G 史上最全的JAVA全套教学视频网盘
- 日常计算机网络基础练习题(每天进步一点点系列)