基于AES ECB 算法的文件加密与解密

2020/08/14 Technology - 次.

基于AES ECB算法的文件加密与解密

高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(例如微信公众平台,百度API等都是采用的这种加密算法)。对称加密算法也就是加密和解密用相同的密钥,具体的加密流程如下图:

密钥,用来加密明文的密码,在对称加密算法中,加密与解密的密钥是相同的。密钥为接收方与发送方协商产生,但不可以直接在网络上传输,否则会导致密钥泄漏,通常是通过非对称加密算法加密密钥,然后再通过网络传输给对方,或者直接面对面商量密钥。密钥是绝对不可以泄漏的,否则会被攻击者还原密文,窃取机密数据。

加密原理

AES加密过程是在一个4×4的字节矩阵上运作,这个矩阵又称为“状态(state)”,其初值就是一个明文区块(矩阵中一个元素大小就是明文区块中的一个Byte)。(Rijndael加密法因支持更大的区块,其矩阵行数可视情况增加)加密时,各轮AES加密循环(除最后一轮外)均包含4个步骤:

  • AddRoundKey — 矩阵中的每一个字节都与该次轮秘钥(round key)做XOR运算;每个子密钥由密钥生成方案产生。
  • SubBytes — 通过非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。
  • ShiftRows —将矩阵中的每个横列进行循环式移位。
  • MixColumns — 为了充分混合矩阵中各个直行的操作。这个步骤使用线性转换来混合每列的四个字节。 最后一个加密循环中省略MixColumns步骤,而以另一个AddRoundKey取代。

加密标准

对称密码体制的发展趋势将以分组密码为重点。分组密码算法通常由密钥扩展算法和加密(解密)算法两部分组成。密钥扩展算法将b字节用户主密钥扩展成r个子密钥。加密算法由一个密码学上的弱函数f与r个子密钥迭代r次组成。混乱和密钥扩散是分组密码算法设计的基本原则。抵御已知明文的差分和线性攻击,可变长密钥和分组是该体制的设计要点。 ​ AES是美国国家标准技术研究所NIST旨在取代DES的21世纪的加密标准。 ​ AES的基本要求是,采用对称分组密码体制,密钥的长度最少支持为128、192、256,分组长度128位,算法应易于各种硬件和软件实现。1998年NIST开始AES第一轮分析、测试和征集,共产生了15个候选算法。1999年3月完成了第二轮AES2的分析、测试。2000年10月2日美国政府正式宣布选中比利时密码学家Joan Daemen 和 Vincent Rijmen 提出的一种密码算法RIJNDAEL 作为 AES. 在应用方面,尽管DES在安全上是脆弱的,但由于快速DES芯片的大量生产,使得DES仍能暂时继续使用,为提高安全强度,通常使用独立密钥的三级DES。但是DES迟早要被AES代替。流密码体制较之分组密码在理论上成熟且安全,但未被列入下一代加密标准。 ​ AES加密数据块分组长度必须为128比特,密钥长度可以是128比特、192比特、256比特中的任意一个(如果数据块及密钥长度不足时,会补齐)。AES加密有很多轮的重复和变换。

大致步骤如下:1、密钥扩展(KeyExpansion),2、初始轮(InitialRound),3、重复轮(Rounds),每一轮又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey,4、最终轮(FinalRound),最终轮没有MixColumns。

代码实现

此处以Python代码为例,以下代码主要是实现将训练好的模型文件进行加密与解密处理,其中MODELAESKEY 是加密与解密的密钥。

from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex


# model file aes encrypt and decrypt
class AESModelEncryptDecrypt(object):

    # aes key complement 16 with zero
    def _add_to_16(self, text):

        if isinstance(text, str): text = text.encode()
        if len(text) % 16:add = 16 - (len(text) % 16)
        else: add = 0
        text = text + ('\13'.encode() * add)
        return text

    # aes encrypt
    def aes_encrypt(self, en_text, model_aes_key):

        key = self._add_to_16(model_aes_key)
        mode = AES.MODE_ECB
        text = self._add_to_16(en_text)
        cryptos = AES.new(key, mode)
        cipher_text = cryptos.encrypt(text)
        return b2a_hex(cipher_text)

    # aes decrypt
    def aes_decrypt(self, de_text, model_aes_key):
        key = self._add_to_16(model_aes_key)
        mode = AES.MODE_ECB
        cryptor = AES.new(key, mode)
        plain_text = cryptor.decrypt(a2b_hex(de_text))
        return plain_text.rstrip('\13'.encode())

    # model file read contents
    def model_file_read(self, model_name):
        with open(model_name, 'rb') as rf:
            contents = rf.read()
        rf.close()
        return contents, model_name

    # model file encrypt
    def model_file_encrypt(self, contents, model_name):
        model_encrypt = self.aes_encrypt(contents, MODELAESKEY)
        with open(model_name, 'wb') as sf:
            pickle.dump(model_encrypt, sf)

    # mode file decrypt
    def model_file_decrypt(self, model_name):
        with open(model_name, 'rb') as rf:
            model_encrypt = pickle.load(rf)
            rf.close()
        model_decrypt = self.aes_decrypt(model_encrypt, MODELAESKEY)
        return model_decrypt

    # aes model file save
    def model_file_save(self, conetents, model_name):

        with open(model_name + '.decrypt_temp', 'wb') as sf:
            sf.write(conetents)
            sf.close()
        return model_name + '.decrypt_temp'

密钥: Kuture

明文:www.kuture.com.cn

模式:ECB

密文:fSTlnkqGpLJz2knbHjcuXVpnTkY1yZCGHdAesOOXkso=

Search

    Table of Contents