古典密码学:
单表替换加密(MonoalphabeticCipher)。
多表替换加密(PolyalphabeticCipher)。
其他加密方式。
现代密码学:
对称加密(SymmetricCryptography),以DES,AES,RC4 为代表。
非对称加密(AsymmetricCryptography),以RSA,ElGamal为代表。
哈希函数(HashFunction),以MD5,SHA-1,SHA-512等为代表。
数字签名(DigitalSignature),以RSA签名,ElGamal签名,DSA 签名为代表。
除此之外,还有一类题型是由出题人用自行编写的某种加密方式进行加密,并提供源码,需要我们通过读代码自己编写解密程序。
对于该类型题目,需要我们读懂加密过程,再编写逆向解密的程序。
+a —— -a
*a —— /a
^a —— ^a
&a —— <=a
|a —— ?
encrypt.1
<?php
error_reporting(0);
show_source("1.php");
functionencrypt($data,$key)
{
$key = md5('BOC-DATACENTER');
$x = 0;
$len = strlen($data);
$klen = strlen($key);
for ($i=0;$i<$len;$i++){
if ($x == $klen){
$x=0;
}
$char .= $key[$x];
$x+=1;
}
for ($i=0;$i<$len;$i++){
$str .= chr((ord($data[$i])+ord($char[$i]))%128);
}
return base64_encode($str);
}
echo"GyZERlYXLydSdFMyUypKVFRDLlQPCmYVHBUnLS4=";
?>
miwen ='GyZERlYXLydSdFMyUypKVFRDLlQPCmYVHBUnLS4=‘
key = hashlib.md5('BOC-DATACENTER'.encode("utf8")).hexdigest()
#base64解密
miwen = base64.b64decode(miwen).decode()
#求char
x=0
char=[]
for i in range(0,length):
if x==klen:
x=0
char.append(key[x])
x+=1
#求(miwen[i]-char[i])%128
data = ''
for i in range(0,length):
data += chr((ord(miwen[i])-ord(char[i]))%128)
bocctf{EnCryption_Is_S0_easy}
加密函数 y = 3x + 9
密文:"JYYHWVPIDCOZ"
查询得知
仿射密码是一种替换密码。它是一个字母对一个字母的。它的加密函数是:
y=ax+b(mod m)
其中a和m互质,m是字母的数目。
解密函数是;
x=a-1(y-b)(mod m)
其中是a的数论倒数。
易得:
解密函数y = 9*(x-9) (modm)
明文:"AFFINECRYPTO"
p=190716027447646792844189733681358379327343061199369341384474902557309769682923254674220284045951117393868651638379541511185212421611653965460100979887725583476037189369599999668327299529542494009290049992057157747007152994025186591269943960410319186487203043168774653327128061548663247131284489765017
q=930788704028200015275140127068138499329817310955
g=220237156062724657086413463831954488565703875839368639153162645824259735475648417436812689270045835305613201869418328189101417845912386944695747737570415063979393239590022180767575736652824918336764694014421673518178065244519367602124516716571334763354973717129155502536345229391073998560517516716958
k = '???'
x = '???'
def data_to_int(s):
return int(s.encode('hex'),16)
def SHA1(data):
return data_to_int(hashlib.sha1(data).hexdigest())
def encrypt(data, p, q, g, x, k):
r = pow(g,k, p) % q
s = (invert(k, q) * (SHA1(data) + x * r)) % q
return (r, s)
data1 = "guest"
data2 = "admin"
(r1, s1) = encrypt(data1, p, q, g, x, k)
(r2, s2) = encrypt(data2, p, q, g, x, k)
print SHA1(data1)
print SHA1(data2)
print s1
print s2
print r1
print r2
d1=SHA1(data1)
d2=SHA1(data1)
s1≡k-1*(d1 + r*x) (mod q)
s2≡k-1* (d2 + r*x) (modq)
k*s1≡d1 + r*x (modq)
k*s2≡d2 + r*x (modq)
k*(s1-s2)≡d1-d2 (modq)
k≡(d1-d2)*(s1-s2)-1(mod q)
x≡(ks1-d1)-1 (modq)
def getflag(data):
print 1
if data == "getflag":
(r, s) = encrypt(data, p, q, g, x, k)
flag = "hctf{"+ str(s %r) + "}"
print flag
k = ((d1-d2)*invert(s1-s2,q))%q
x = (k*s1-d1)*invert(r,q)%q
getflag("getflag")
hctf{88169191231439818447681393510021281730269252095}
encrypt.2
加密数据.txt
/\t\nTP9\t\nTP9k\n\tRXpVUNRVWZdEWS5URVNTWHRlQNdERy\t\n\t\nRWJlTHR\t\nMVd\t\nVC9\t\nRENTTHRlWNtERzU\n\tRUJVTHRFNNdUWa\n\t\t\nUUpVVHdlUO\n\tEVz\t\n\t\nRapVTHR\t\nMNd\t\nVK\n\tUTUpVTHNlUOlERzQzRUJkTNRlMZdUWa\n\t\t\nRENDNHRlSN\n\tERDVzR
加密过程
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import base64
flag = "flag{}"
def encode(string):
x = ""
string = string[::-1]
string = base64.b64encode(base64.b32encode(base64.b16encode(string)))
string = string[::-1]
for i in range(len(string)):
if string[i]=='=':
x += '/'
elif string[i] == '0':
x += '\\t\\n'
elif string[i] == '1':
x += '\\n\\t'
elif string[i] == '2':
x += '\\t'
else:
x += string[i]
return x
if __name__ == '__main__':
print encode(flag)
方法一(本题推荐):
文本量不大——手工替换
方法二:
编写程序
#倒序
miwen1 = miwen1[::-1]
#base解密
miwen1 =base64.b16decode(base64.b32decode(base64.b64decode(miwen1))).decode()
#倒序
mingwen = miwen1[::-1]
flag{604ece863e52989ef79cca3bd7de8c7a}
int main()
{
char czHelloworld[] ="\x60\x43\x31\x05\x68\x19\x6c\x3e\x30\x1c\x63\x1a\x6f\x14\x72\x64";
char czPassword[20]= {0};
printf("Pleaseinput password:\n");
scanf("%16s",czPassword);
for (int i =0; i < strlen(czHelloworld);i++)
{
czHelloworld[i] =czHelloworld[i] +3;
}
for (int i =0; i < strlen(czPassword);i++)
{
for (int j =i; j < strlen(czPassword);j++)
{
czPassword[i] ^= czPassword[i+1];
}
}
if (!strcmp(czHelloworld,czPassword))
{
printf("Right!\nflag isthe password with flag{}\n");
}
else
{
printf("wrongpassword!\n");
}
return 0;
}
密文
for (int i = 0; i < strlen(czPassword);i++)
{
for (int j =i; j < strlen(czPassword);j++)
{
czPassword[i] ^= czPassword[i+1];
}
}
miwen=[]
for i in range(0,16):
miwen.append(ord(czHelloworld[i])+3)
方法一:直接解密
for i in range(14,-1,-1):
for j in range(i,16):
miwen[i]^= miwen[i+1]
for i in range(0,16):
miwen[i] =chr(miwen[i])
print(''.join(miwen))
方法二:利用运算性质解密
第i个元素与后一位异或了(16-i)次
与同一元素异或2次
偶数位不变化,奇数位与后一位异或
逆函数为其本身
for i in range(1,15,2):
miwen[i]^= miwen[i+1]
for i in range(0,16):
miwen[i] =chr(miwen[i])
print(''.join(miwen))
cr4cksor3yforbug
def usage():
print("Usage: %s [encrypt/decrypt] [in_file] [out_file] [password]" % sys.argv[0])
exit()
def main():
if len(sys.argv)< 5:
usage()
input_data =open(sys.argv[2],'r').read()
result_data =""
if sys.argv[1]== "encrypt":
result_data =encrypt(input_data, sys.argv[4])
elifsys.argv[1]== "decrypt":
result_data =decrypt(input_data, sys.argv[4])
else:
usage()
out_file =open(sys.argv[3],'w')
out_file.write(result_data)
out_file.close()
def xor(input_data, key):
result = ""
for ch in input_data:
result += chr(ord(ch) ^key)
return result
def encrypt(input_data, password):
key = 0
for ch inpassword:
key ^= ((2 * ord(ch) +3) & 0xff)
return xor(input_data,key)
def decrypt(input_data, password):
return encrypt(input_data,password)
难点:password未知
方法一:尝试破解key:
该加密方式本质是一种替换密码,而英文中不同字符出现的概率是有差别的。空格出现的概率最大。找出密文中出现最多的字符,即可算出k。
fr = open(r"D:\XOR\encrypted.txt",'r')
miwen = fr.read()
from collections import Counter
frequency = Counter()
with open(r"D:\XOR\encrypted.txt", 'r') as f:
data = f.read()
for ch indata:
frequency[ch] +=1
c = frequency.most_common(10)[0][0]
m = ' '
print (repr(c) + ' decrypts to ' + repr(m))
k = ord(c)^ord(' ')
print(k)
print(xor(miwen,k))
'\x9a' decrypts to ' '
186
This message is for Daedalus Corporationonly. Our blueprints for the Cyborg are protected with a password. That password is bde028b9ddeb2b7e80b9fcfee00e2f
方法二:暴力破解
def encrypt(input_data, password):
key = 0
for ch inpassword:
key ^= ((2 * ord(ch) +3) & 0xff)
return xor(input_data,key)
key = ((2 * ord(password[0]) + 3)& 0xff)^ ((2 * ord(password[1])+ 3)& 0xff)^…
((2 * ord(ch) + 3) & 0xff) ≤ 255
两个不大于255异或的结果不大于255
若干不大于255异或的结果不大于255,key<=255
defxor(input_data, key):
result = ""
for ch in input_data:
#明文一定是可显示字符,筛除不合条件的k值
if ord(ch) ^key not in range(20,127):
return None
result += chr(ord(ch) ^key)
return result
fr= open(r"D:\XOR\encrypted.txt",'r')
miwen = fr.read()
for key in range(0,256):
result = xor(miwen,key)
if result != None:
print(result)
This message is for Daedalus Corporationonly. Our blueprints for the Cyborg are protected with a password. Thatpassword is bde028b9ddeb2b7e80b9fcfee00e2f