blog/_posts/2022-10-14-crack-aes.md

62 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
layout: post
title: 如何破解我上次写的加密程序?
tags: [Python, 加密, 破解]
---
不按规则使用加密算法是非常不安全的!<!--more-->
# 起因
前几天我用Python写了一个[很简单的加密程序](/2022/10/08/tinyaes.html)用的是tinyaes提供的AES-128-CTR加密方式然后因为嫌麻烦没有整iv。最近几天我一直在搜关于AES中关于iv的信息我一直没想明白那个iv到底是干啥用的。
在我看了几天那些关于AES的5种加密模式之后关于ECB和CBC的加密模式讲的很多而对其他加密模式讲的很不清楚……但唯一写的很清楚的就是ECB很不安全重复使用相同的密钥和iv加密数据很不安全尤其是CTR模式直接完全丧失了机密性😂这不是在完全否定我前几天写的东西嘛然而除了这些就再没有写别的了……那它到底是怎么个丧失了机密性啊又不说清楚所以就只好我自己想了😓。
# 探索
首先我先看了看AES中5种加密模式的区别发现CTR模式和其他模式有个不同的地方是它加密的是密码而不是数据它是把密码和iv通过AES加密算法加密之后把获得的东西和明文数据异或后来得到密文的怪不得它可以加密和解密用相同的方法原来它真的就是异或加密啊😂那异或加密安全吗我在网上也搜了搜很多人说这是一种非常不安全的加密方式只有不懂的人和刚入门密码学的人才会用巧了我就是不懂密码学的人😂然而异或加密又怎么不安全网上又不说……我真的是无语了。
不说我就只能自己想了……首先他们说CTR不安全的加密仅限于相同的iv和密码去加密不同的数据而加密的方式是通过异或那么我们先这样去算一下
K = AES(key, iv)
C1 = K xor P1
C2 = K xor P2
其中K是用AES加密密码和iv获得的值C代表密文P代表明文。然后想着想着如果用C1 xor C2会怎么样呢最终用异或运算律算了一下大概明白了为什么它不安全了因为
C1 xor C2 = P1 xor P2
我们知道在这种情况下假如你用P1或P2去异或上面式子得到的值那你就能得到另一个明文也就是
(C1 xor C2) xor P1 = P2
这样你只要知道一组用这个密钥加密的密文和明文,就能破解所有其他密文了!
于是根据这个原理我试着用Python写了一个根据已知明文密文对获得密文的程序出来
```python
import sys
if not len(sys.argv) == 4:
exit(f"Usage: {sys.argv[0]} [enc_file1] [enc_file2] [plain_file2]")
with open(sys.argv[1], "rb") as enc_file1:
with open(sys.argv[2], "rb") as enc_file2:
with open(sys.argv[3], "rb") as plain_file2:
with open(sys.argv[1] + ".crack", "wb") as crack_file1:
crack_file1.write(bytes(a ^ b for (a, b) in zip(bytes(a ^ b for (a, b) in zip(enc_file1.read(), enc_file2.read())), plain_file2.read())))
```
写完之后发现和加密的程序用了一样多的行数😂,试了一下,真的可以获得另外密文的对应的明文!而且是在不需要知道密码的情况,不过我不知道是我程序写的有问题还是推算的有问题,当想要破解的文件长度比已知明文密文的文件长时,破解出来的明文就只能破解到和已知明文密文一样长的位置……总之能证明之前写的加密确实“完全丧失了机密性”就行了。
# 解决办法
为了弥补上一篇文章写的加密程序所遇到的问题这次我还是乖乖的按照官方说明使用iv吧根据这个原理我重新写了一下我的程序
```python
import hashlib, tinyaes, sys, os
if not len(sys.argv) == 3:
exit(f"Usage: {sys.argv[0]} [filepath] [key]")
enc = False
if len(sys.argv[1]) > 4:
if sys.argv[1][-4:] == ".enc":
enc = True
with open(sys.argv[1], 'rb') as orig:
iv = os.urandom(16)
key = tinyaes.AES(hashlib.md5(sys.argv[2].encode()).digest(), orig.read(16) if enc else iv)
with open(sys.argv[1][:-4] if enc else sys.argv[1] + ".enc", 'wb') as targetfile:
if not enc:
targetfile.write(iv)
for byte_block in iter(lambda: orig.read(4096), b''):
targetfile.write(key.CTR_xcrypt_buffer(byte_block))
```
这次我把随机生成的iv存到了文件的开头不过也正是如此我没办法用完全相同的办法去进行加密和解密了……所以用了`.enc`后缀名作为明文和密文的区分。还有程序的行数几乎增加了一倍😂。
# 感想
看来对于不太了解的学科还是好好的按照人家说明书上写的做比较好,不然不懂装懂就会达不到预期的想法了。