熟悉防空系统的朋友们都知道,防空系统中的大量数据一般都是以明文形式存储于数据库和文件中。为了保障防空系统中重要数椐的安全性,需要对这些数据进行加密后再存储。经过多方对比,我们选择了高安全性能的AES算法作为加密算法。该方法具有较高的安全性能,同时又易于实现,具有良好的推广价值。
一、AES加密算法基本原理
AES加密算法把一个分组看成是4x4的二维字节(1字节8bit)数组,称此数组为State状态矩阵。加密解密就是对State进行多次变换以获得密文或明文的过程。该加密算法主要由KeyExpansion(密钥扩展)和轮循环组成,每轮由SubBytes(字节变换)、ShiftRows(行移位)、MixColumns(列混合变换)和AddRoundKey(轮密钥加)组成。解密算法是加密算法的逆过程,每轮由InvSubBytes(逆字节变换)、InvShiftRows(逆行移位)、Inv-MixColumns(逆列混合变换)和AddRoundKey(轮密钥加)组成。AES-128、AES-192,AES-256对应的轮循环次数分别为10,12和14次。
(1) SubBytes(字节变换)
字节变换是一个非线性的字节替代变换。由于其运算比较复杂,在编程时通常采用查S盒列表的方式,输入为8 bit,输出仍为8 bit。字节变换的逆向变换相应的在一个逆S盒中进行查表操作。
(2) ShiftRows(行移位)
行移位是对State矩阵的移位操作。State矩阵的第l行保持不变,第2行循环左移l位,第3行循环左移2位,第4行循环左移3位。逆行移位将左移改为右移。
(3) MixColumns(列混合变换)
在列混合变换中,把State矩阵的每一列都看作有限域上的多项式,与一个固定的矩阵相乘。逆列混合变换为正矩阵变换的逆变换。
(4) AddRoundKey(轮密钥加)
将State矩阵中的每个字节和轮密钥的对应字节进行按位异或操作。
(5) KeyExpansion(密钥扩展)
密钥扩展的输入是16字节的密钥,输出是156字节的线性数组,每16个字节组成一组用于算法中初始轮密钥加和另外10轮中每轮的轮密钥加操作。
AES加密算法的解密过程与加密过程类似,但轮循环的步骤顺序不一样。AES-128的加密和解密流程如图1所示。与DES加密算法相比,AES加密算法的实现更简单。同时由于AES加密算法具备很强的扩散性能,最终形成的密码有很高的随机性,抗分析攻击能力强。
二、加密模块设计
在数据库中存储的字段,无论字符、数字还是时间类型,均可以看做一组字符串。每个字符在电脑中均是以8bit的数字所表征,那么对于128 bit长度的分组,一个分组就有16个字符。对于长度不满16个字符的字符串,需要在尾部填充字符,并标记原字符和填充字符;对于超过16个字符的则需要分组进行加密处理。
在本文中采用‘/0’作为字符串的结尾符。而对于填充字符,如果全部采用一种字符来填充,则浪费了填充字符的作用。因为对于AES算法来说,输入的明文是定长的,完全可以利用填充字符来增加明文之间的差异性,令加密后的密文更难破解。因此本文设计了使用随机字符的方法来填充字符串。首先申请一段16个字符的字符数组,但不做初始化。然后将明文复制到数组中,并以‘/O’结尾。那么剩余的数组字符就是内存中的随机数。这样即使对于同一段明文,每次加密的密文都会不一样,增加了破解难度和猜测的可能性。
基于以上的设计,加密步骤如下:
(1)获得需要加密的明文和设定的密钥Key。
(2)根据明文长度进行处理。大于16个字符的明文按16个字符分组,最后一组如果长度小于16则在尾部加上‘/o’做结尾,剩余的填充随机字符;对于长度小于16个字符的明文,直接按照上述最后一组的方法处理。
(3)对每个16字符分组进行加密,得到密文。
(4)将密文组合,按照8 bit的分法输出字符,或是按照4 bit的分法输出16进制数值;
(5)将密文保存到数据库或文件中。
对于分组加密后的密文,其长度也是128 bit。如果按照8 bit划分并转化为字符输出,是16个字符。但是这8 bit的数值可能超过ASCH码的范围,因此显示出来的密文就是乱码,可读性较差,但是能保证密文长度不变D如果按照4 bit划分,则可以用16进制的方式显示,但是显示出来的密文长度是32个字符,比明文多了一倍。在应用中可以根据情况选择不同的密文输出方式。不同的密文输出方式在解密时需要做相应的处理。
三、解密模块设计
解密时,需要根据密文的显示形式做出处理。乱码形式的密文,按16个字符的长度分组然后解密;16进制的密文,按32个字符的长度分组,对每个分组将32个字符转化成16个字符的密文,然后再解密。解密步骤如下:
(1)从数据库或文件中获得密文和与加密时相同的密钥Key。
(2)对密文进行处理,乱码形式的密文直接按16个字符的长度分组;16进制的密文按32个字符分组,然后将每组的32个字符转化成16字符密文。
(3)对每个16字符密文进行解密,获得明文。
(4)将明文组合,并根据‘/O’字符去掉多余的填充字符;
(5)输出明文。
四、防空系统中AES加密算法的应用
本文采用C++语言编写了AES-128的加密和解密函数,并生成了Cipher.dll动态库。采用C++语言的优点是高效和可跨平台,生成动态库则可以方便地被VC++或QT开发的软件所调用。
1、防空系统数据库加密
在防空系统的数据库中,用户密码是一个关键的数据项。如果一旦密码被泄漏,他人就可以冒充用户进行操作,造成严重后果,因此用户密码必须加密。用户的密码长度设定在4-15个字符,不超过16个字符,因此无需分组。对于密文,采用16进制的方式显示。数据库中存储的密文如图2所示。
这些密码的原文均是“1234”,但是由于随机字符的填充,导致加密后的密文完全不一样,避免了猜测的可能性,有效隐藏了密码的长度和相同密码。
2、防空系统文件加密实例
在防空系统中,连接数据库需要参数,而这些参数都要保存在配置文件中,因此需要对配置文件进行加密。配置文件通常很小,所以采用全文件加密的方式,并且以字符形式保存密文。原文件如图3所示,加密后的文件如图4所示。
从加密后的文件可以看出,密文完全隐藏了原文件的格式和内容,不具备可读性。
小知识之QtQt是一个1991年由奇趣科技开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,易于扩展,允许组件编程。