2.1 软件总体流程

在信息安全中,安全通信需要具有以下三个特性[8]。①机密性,仅有发送者和接受者能够理解传送信息的含义,保证信息在传输时不被泄露。②完整性,需要确保信息在传输过程中不被篡改。③有效性,也称端点鉴别,即发送方和接收方都能证实通信的另一方确实具有他们声称的身份,确保信息的使用者时合法的。为了使开发的软件保护程序满足安全通信的三要素,利用公私钥密码来解决机密性,利用数字签名解决完整性和有效性问题,完成了基于证书的签名和认证程序。

2.1.1 基于证书的签名程序

对于Linux下给定的ELF可执行程序进行签名,主要包括以下四个步骤,如图2-1所示。

图2-1 ELF 文件加密流程

(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 基于证书的验证程序流程

2.2 内置UOS公钥与内核钩子程序

为了保证内核代码不被修改,同时也为了维护测试的方便性,开发外置内核模块,挂钩Linux内核的进程启动流程作为ELF签名文件的验证程序。开发钩子函数,挂钩住ELF的执行入口函数“load_elf_binary”,并在外置的钩子中实现ELF认证签名文件、公钥、证书的读取及验证工作。验证通过则返回原入口函数处继续运行ELF文件,否则停止运行该ELF文件。

2.2.1 钩子的定义

钩子[9]表示一个允许编程者插入自定义程序的地方,通常是打包好的程序中提供的接口。通过钩子,可以实现暂停系统调用,或通过改变系统调用的参数来改变正常的输出结果,甚至可以终止一个当前运行的进程并将控制权转移到程序员的手中。钩子执行示意图如图2-3所示。

图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”。接着会执行被钩住函数中被跳转指令所覆盖的执行,最后回到被钩住函数的正常执行逻辑。

a)未加钩子的函数调用
b)加入钩子的函数调用

2.2.3 内核钩子程序

在第一章中分析了ELF文件的执行流程,其中ELF中的加载程序为load_elf_binary。为了保证不修改内核源码,需要开发外置内核模块挂钩Linux内核的进程启动流程作为验证程序。因此钩子需要钩住load_elf_binary函数。通过挂钩,实现在调用ELF可执行文件之前,对ELF文件进行签名及验证。

在内核中有两种函数。一种是在内核中已经定义了函数声明的函数,另一中是在内核中未声明的,只是.c内部使用的函数。load_elf_binary属于第二种类型的函数。因此需要如下的方式进行钩子函数的定义。

  1. #include <linux/binfmts.h> // has no load_elf_binary() proto
  2. KHOOK_EXT(int, load_elf_binary, struct linux_binprm *);
  3. static int khook_load_elf_binary(struct linux_binprm *bprm)
  4. {
  5. int ret = 0;
  6. ret = KHOOK_ORIGIN(load_elf_binary, bprm);
  7. return ret;
  8. }

通过上述函数,就得到了用于钩住load_elf_binary函数的自定义的钩子函数(其它前期操作不做赘述)。在此钩子函数中需要完成ELF可执行文件加载之前的签名和验证工作,包括读取开发者公钥、读取ELF认证文件、验证开发者公钥、验证ELF认证文件等,流程如图2-5所示(流程图中只是展示函数运行的主要过程,并不是函数执行的具体过程,即并没有表明当读取或验证失败后的流程)。

图 2-5 load_elf_binary钩子函数的执行流程

如图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文件。由此可见基于公私钥的签名认证程序是存在缺陷的,也就是无法确保公钥的合法性。

图 2-6 基于公私钥的验证流程

要使公钥密码有用,就要能够证实通信的另一方确实具有他们声称的身份。为了验证公钥的合法性,就要涉及到数字签名的另一个重要的应用“公钥认证”,即证实公钥属于某个特定的实体。将公钥于特定的实体绑定通常是由认证中心完成的,CA的职责就是使识别和发行证书合法性。

2.3.2 公钥证书实现

在UOS系统下实现基于签名技术的软件保护程序,这里的验证中心即为UOS官方的认证中心。为了确保证书在传输过程中不被篡改,首先对开发者公钥进行SM3国密算法计算其散列值,再利用认证中心的私钥进行加密,得到公钥的认证证书,如图2-7所示。

图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-8 追加验证部分的ELF文件格式

2.5 用户使用ELF文件

开发基于证书的验证软件并加入操作系统,在运行任何ELF可执行程序前对ELF文件进行验证,若ELF可执行程序没有被签名或者签名验证失败则应停止运行本程序,若签名验证成功则可以正常运行。

在用户使用ELF文件之前,需要对ELF文件进行验证。验证程序是由外置的内核钩子完成的,确保不修改内核代码,运行ELF可执行程序的方式保持不变。根据加密的过程,可以很自然得到验证签名的过程。签名与加密过程如图2-9所示。四个部分均作为单独的节附加在ELF文件的末尾,因此可以根据文件格式分别读取出ELF源文件、开发者公钥、数字签名验证这三个部分。

首先,需要验证附加在ELF文件中开发者公钥的合法性。利用UOS认证中心的私钥解密认证文件,得到开发者公钥的散列值。并对读取得到的开发者公钥进行SM3国密算法散列,将两个散列值进行对比,若相等,则证实了附加在ELF文件中公钥的合法性。

接着读取附加在ELF文件中的签名认证部分,利用合法的公钥对其进行解密,得到ELF文件中代码段的散列值。

最后读取ELF文件中的代码段,并求其散列值,再将这两个散列值进行对比,若相等,则该ELF文件认证通过,并执行该认证文件;否则,认证不通过,中断该ELF文件的执行。

图 2-9 基于证书的签名和认证程序过程对比图

linux 下 c++ 实现 netstat_Linux下基于签名技术的软件保护之实现流程相关推荐

  1. hadoop下计算机网络安全设计与实现,基于PKI技术的网络安全平台设计研究

    科技信息 0 IT技术论坛0 SCIENCE&TECHNOLOGY INFORMATION 2008年 第4期 基于 PKI技术的网络安全平台设计研究 马 (陕西交通职业技术学院 骞 陕西 西 ...

  2. web html5音乐播放器设计与实现,基于HTML5技术的音乐播放器的设计与实现

    Vol.33No.11Nov.2017 赤峰学院学报(自然科学版) Journal of Chifeng University (Natural Science Edition )第33卷第11期(下 ...

  3. 基于html的音乐播放设计,基于HTML5技术的音乐播放器的设计与实现

    Vol.33No.11 Nov.2017 赤峰学院学报(自然科学版) JournalofChifengUniversity(NaturalScienceEdition) 第 33 卷第11 期(下) ...

  4. 一个Linux下的 俄罗斯方块游戏,基于 ncurse 库。。

    2019独角兽企业重金招聘Python工程师标准>>> 几天前写得一个Linux下的 Tetris 游戏,基于 ncurses  库.. 望大家多多指教,功力太浅,多提代码的改进意见 ...

  5. linux环境用opencv读取图片,基于Linux下OpenCV的人脸识别模块设计

    金笑雪 张琳琳 高丹 张黎 摘 要: 近年来,图像识别技术正在向更加直观.可靠的方向发展,其中人脸识别技术具有极高的研究价值,应用得也最为广泛.通过对Linux系统下OpenCV的研究,利用OpenC ...

  6. linux下开发教务管理系统c,基于Linux/NC中小学的资源管理和互动教学系统

    1 引 言本文引用地址:http://www.eepw.com.cn/article/90252.htm Linux最早是由芬兰大学生Linus Torvalds于1991年开发的,其借鉴Unix系统 ...

  7. linux secure boot(安全启动)下为内核模块签名

    文章目录 linux secure boot(安全启动)下为内核模块签名 背景 Secure Boot安全启动开启关闭方法 内核驱动签名 生成签名证书和私钥 导入签名证书 BIOS(UEFI)导入证书 ...

  8. Linux下配置Apache虚拟主机(基于IP地址)

    Linux下配置Apache虚拟主机(基于IP地址) 一.虚拟主机 虚拟主机,又称虚拟服务器,是一种在单一主机或主机群上,实现多网域服务的方法,可以运行多个网站或服务的技术.虚拟主机之间完全独立,并可 ...

  9. linux安装基于PHP的web软件,Linux下Web服务器应用之基于LAMP构建phpwind论坛

    Linux下Web服务器应用之 基于LAMP构建phpwind论坛 v什么是LAMP Ü目前最为成熟的一种企业网站应用模式,可提供动态Web站点应用及开发环境 v构成组件 ÜLinux.Apache. ...

最新文章

  1. H264 NALU 使用PS封装 RTP发送
  2. 在企业环境中部署 Microsoft Windows 恶意软件删除工具
  3. IT兄弟连 Java语法教程 Java的发展历程
  4. 如何判断京东达人文章是否下线
  5. 计算机管理内默认共享,关于Windows的默认共享介绍
  6. 如何用报表解决销售工作衡量问题
  7. java中的URLConnection
  8. 如何禁用Web表单字段/输入标签上的浏览器自动完成功能?
  9. 学术论文写作的 paper、code 资源
  10. java基础之static
  11. 思科CCNA考试流程-ielab
  12. 超神四年的王者荣耀 会被英雄联盟手游顺利推塔吗?
  13. java scjp 试题_SCJP(JAVA)试题一套!求答案...
  14. 通过split命令分割大文件
  15. docer-compose
  16. 我赢助手:视频不清晰很模糊,和原片差别很大该怎么办?作品零播放是怎么回事?
  17. Tomcat 运行 maven项目报错 com.sun.faces.config.ConfigureListener
  18. 天猫店群起店新玩法,安全稳定,天猫店群全店动销退款单后的玩法
  19. 500G 史上最全的JAVA全套教学视频网盘
  20. 日常计算机网络基础练习题(每天进步一点点系列)

热门文章

  1. 一段比较经典的多线程学习代码
  2. 使用XStream进行对象和xml的转换,极度舒适
  3. PowerDesigner(九)-模型文档编辑器(生成项目文档)
  4. java对mysql的简单操作的综合运用——修改密码系统
  5. zabbix 配置mysql_zabbix 配置mysql监控
  6. java工程师面试经典题目整理
  7. Redis手动failover
  8. 权限管理(1):简介
  9. AHK 中的字符串拼接和遍历操作
  10. 遍历lucene索引库的字段名