专栏首页readmeAES 高级加密标准
原创

AES 高级加密标准

The Advanced Encryption Standard (AES), also known by its original name Rijndael, is a specification for the encryption of electronic data established by the U.S. National Institute of Standards and Technology (NIST) in 2001.

1997年1月2号,美国国家标准技术研究所(National Institute of Standards and Technology: NIST)宣布希望征集高级加密标准AES用以取代DES。最终经过安全性分析、软硬件性能评估等严格的步骤,Rijndael算法获胜。在2001年建立了电子数据的加密规范。它是一种分组加密标准,每个加密块大小为128位,允许的密钥长度为128、192和256位。AES加密算法涉及4种操作:字节替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥加(AddRoundKey)。

# pip install pycrypto
from Crypto.Cipher import AES
from Crypto import Random

key = b'Hello world  ~~~' # *16
iv = Random.new().read(AES.block_size)
cipher = AES.new(key, AES.MODE_CFB, iv)
msg = iv + cipher.encrypt(b'Attack at dawn')
print(key,msg)

# MODE_ECB = 1 Electronic Code Book (ECB). See blockalgo.MODE_ECB.
# MODE_CBC = 2 Cipher-Block Chaining (CBC). See blockalgo.MODE_CBC.
# MODE_CFB = 3 Cipher FeedBack (CFB). See blockalgo.MODE_CFB.
# MODE_PGP = 4 This mode should not be used.
# MODE_OFB = 5 Output FeedBack (OFB). See blockalgo.MODE_OFB.
# MODE_CTR = 6 CounTer Mode (CTR). See blockalgo.MODE_CTR.
# MODE_OPENPGP = 7 OpenPGP Mode. See blockalgo.MODE_OPENPGP.
# block_size = 16
# Size of a data block (in bytes) key_size = (16, 24, 32)
# Size of a key (in bytes)
  • Electronic Code Book (ECB) 电码本模式

将整个明文分成若干段相同的小段,然后对每一小段进行加密。ECB是最简单的块密码加密模式,加密前根据加密块大小(如AES为128位)分成若干块,之后将每块使用相同的密钥单独加密,解密同理。

  • Cipher-Block Chaining (CBC) 密码分组链模式

先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。CBC模式对于每个待加密的密码块在加密前会先与前一个密码块的密文异或然后再用加密器加密。

  • Cipher FeedBack (CFB) 密文反馈模式

与ECB和CBC模式只能够加密块数据不同,CFB能够将块密文(Block Cipher)转换为流密文(Stream Cipher)。

  • Output FeedBack (OFB) 输出反馈模式

密码算法的输出(指密码key而不是密文)会反馈到密码算法的输入中,OFB模式并不是通过密码算法对明文直接加密,而是通过将明文分组和密码算法的输出进行XOR来产生密文分组。OFB是先用块加密器生成密钥流(Keystream),然后再将密钥流与明文流异或得到密文流,解密是先用块加密器生成密钥流,再将密钥流与密文流异或得到明文,由于异或操作的对称性所以加密和解密的流程是完全一样的。

  • CounTer Mode (CTR) 计数器模式

完全的流模式。将瞬时值与计数器连接起来,然后对此进行加密产生密钥流的一个密钥块,再进行XOR操作 。

import base64
from Crypto.Cipher import AES

def add_to_16(value):
    while len(value) % 16 != 0: value += '\0'
    return str.encode(value)  # 返回bytes

def encrypt_AES(text, key):
    aes = AES.new(add_to_16(key), AES.MODE_ECB)
    encrypt_aes = aes.encrypt(add_to_16(text))
    return str(base64.encodebytes(encrypt_aes), encoding='utf-8')

def decrypt_AES(text, key):
    aes = AES.new(add_to_16(key), AES.MODE_ECB)
    base64_decrypted = base64.decodebytes(text.encode(encoding='utf-8'))
    decrypted_text = str(aes.decrypt(base64_decrypted),encoding='utf-8').strip()
    for i in range(16): decrypted_text = decrypted_text.replace(chr(0x00+i),'')
    return(decrypted_text.replace(chr(0x10),''))

if __name__ == "__main__":
    key = 'UITN25LMUQC436IM'
    raw = encrypt_AES("hello world",key)
    res = decrypt_AES(raw,key)
    print(raw, res)

------------------------------ AES Attacking

  • 暴力攻击又称为穷举攻击
  • 侧信道攻击(side channel attack, SCA),

又称旁路攻击、旁道攻击、边信道攻击,是指通过窃取电子设备实现加解密算法时泄露的旁路信息从而攻击密码系统的方法,例如通过分析密码系统的计算时间、功率消耗、电磁辐射和声音情况等“听译”密钥破解密码。与传统的通过数学手段的密码分析不同,SCA并不直接攻击已证明运算安全的密码算法本身,而采取了一种“曲线救国”的方式攻击密码算法的实现技术,破解密码系统的效果更为显著。好比想知道一个人在家中是在洗衣服还是看电视,我们并不需要撬开门锁进入屋子一探究竟,直接通过观察室外的水表和电表便可推测出来,SCA正是这样一种绕开门锁的窥探方法。

侧信道攻击是目前针对AES密码系统唯一成功的攻击,但实际上该攻击并不仅仅对AES有效,很多其他的密码系统也同样有侧信道攻击的安全隐患。AES算法本身是足够安全了,只可惜栽在了算法实现上,“不怕神一样的对手,就怕猪一样的队友”,大抵说的就是这种情况吧。

侧信道攻击之所以可行主要在于电子密码设备泄露的时间、功率、电磁辐射等旁路信息和设备所运算的数据具有一定的关联性。在硬件电路层面,可以通过功耗平衡等技术减弱这种关联性;从软件算法实现层面,则可通过“掩码”或“隐藏”等牺牲一定运算效率的方法以混淆攻击者的视听,从而保证密码算法的安全性。

------------------------------

向包含未知字符串的明文中插入数据,其实也是枚举验算的过程

  • 获取未知字符串的第一位

比输入name为111111111111,服务器生成未知字符串"hello, 111111111111, your mission's flag is:  FLAGXXXXXX"的用ecb加密过的字符串S1给我们,其中FLAGXXXXXX是我们希望得到的flag,通过观察题目程序可知,此处ECB使用的是16位的,进而观察可知,16个字符的字符串加密后就变成32个字符的密文了。

就是说"hello, 111111111111, your mission's flag is:  X"的最后一个X刚好是第32位,我们首先通过这个32字符的字符串获取一下加密过的encrypto, 也就是64个字符的字符串S2,那么这个S2必然是S1的前64位。然而我们刚开始并不知道这个X是什么,于是我们枚举这个X,令X为一个ascii字符,

比如向服务器发送"hello, 111111111111, your mission's flag is:  A",获取密文,如果这个密文恰好是S1的前64位,那么A就是flag未知字符串的第一位,于是我们就破解了flag的第一位。

  • 获取未知字符串的剩余位

因为A已经是flag的第一位,根据破解的原理,我们要把未知字符放在第32位(此处和第一步一样取一个合理的16的倍数)那么我们只要把name的名字长度缩小一个字符就可以了,即此时变为  "hello, 11111111111, your mission's flag is:  AX"

(可以对照第一步的字符"hello, 111111111111, your mission's flag is:  A")依然枚举X即可,以此类推,获取全部的字符串(此处以"}"为结尾标志)

https://blog.csdn.net/u014549283/article/details/81486284

https://zachgrace.com/posts/attacking-ecb/

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • two.js konvas.js helloworld

    两个画图用的JS框架。前端框架的名字都蛮有意思的, two.js - three.js - D3.js , canvas - konvas.js , view ...

    readme
  • PI 圆周率

    3.141592653589793238462643383279502884197169399375105820974944592307816406286208...

    readme
  • IP camera access 网络摄像头调用

    GoPro访问基于无线网络连接和socket直接访问udp资源,实测视频延迟有点厉害,应该还是码流/压缩的原因,访问有些应用层的rtsp协议相对更快,同时Op...

    readme
  • 适配器模式

    1.缺少兔子类对象,先用狗类冒充一下 2.不会让客户调用兔子类的方法,发生改变(例如在客户调用的方法内做判断如果是某个值,去调用狗类的方法,去冒充兔子类)

    杨小杰
  • pagination使用说明

    下载jquery.min.js 下载jquery.pagination.js 下载pagination.css

    Theone67
  • Spring Boot 外部化配置实战解析

    在 SpringApplication#run(String... args) 方法中,外部化配置关键流程分为以下四步

    宜信技术学院
  • (数据科学学习手札56)利用机器学习破解大众点评文字反爬

      爬取过大众点评的朋友应该会遇到这样的问题,在网页中看起来正常的文字,在其源代码中变成了下面这样:

    Feffery
  • python 三级菜单

    用户选择菜单的时候,如果输入中文,打字比较麻烦,菜单列表需要有一个编号。由于字典没有编号,列表是有索引,这里可以用做编号。所以需要将zone.keys()的结果...

    py3study
  • 人群密度估计

    DecideNet: Counting Varying Density Crowds Through Attention Guided Detection an...

    用户1148525
  • js跳转界面

    js页面跳转大全 所谓的js页面跳转就是利用javesrcipt对打开的页面ULR进行跳转,如我们打开的是A页面,通过javsrcipt脚本就会跳转到B页面。 ...

    用户1219438

扫码关注云+社区

领取腾讯云代金券