密码学
古典密码:单表替换加密(Monoalphabetic Cipher)多表替换加密(polyalphabetic Cipher) 奇奇怪怪的加密方式
现代密码:1949香农 对称加密(分组密码(块密码)、序列密码(流密码)) 非对称加密 哈希函数 数字签名
目的:机密性(Confidentiality)完整性(Integrity)可用性(Availability)认证性(Authentication)不可否认性(Non-repudiation)前三者CIA三要素
攻击类型通常分为以下四种:
唯密文攻击 只拥有密文
已知明文攻击 拥有密文与对应的明文
选择明文攻击 拥有加密权限,能够对明文加密后获得相应密文
选择密文攻击 拥有解密权限,能够对密文解密后获得相应明文
ASCII码(使用7个二进制位对字符进行编码)
0 b6 b5 b4 b3 b2 b1 b0
用1个字节存放有效7位ASCII,最高位位0. 共有2^7 128个
最大 0111 1111 最小 0000 0000 0-127D\0-7FH
b6b5b4在000与001与b3b2b1b0组成34个控制字符,b6b4b5在010 011 100 101 110 111与b3b2b1b0组成94个可打印字符。
base64
原数据 | M-0x4d | Z-0x7a | 1-0x31 | ||
二级制原数据 | 0100 1101 | 0111 1010 | 0011 0001 | ||
重新分割 | 3*8重新分为 | 4*6 | |||
对应数字 | 19 | 23 | 40 | 49 | |
对应字符 | T | X | O | x |
RSA
公私钥的生成
1.选择一堆不相等且足够大的质数 p;q
2.计算p;q的乘机
3.计算n的欧拉函数 φ(n)=(p-1)*(q-1)
若n可以分为2个互质整数之积,那么n的欧拉函数等于这两个因子的欧拉函数之积木,即若n=p*q且p,q互质则φ(n)=φ(p*q)=φ(p)*φ(q)
φ(质数)=该质数-1
4.选择一个与φ(n)互质的整数e 1<e<φ(n)
5.计算出e对于φ(n)的模反元素d de mod φ(n)=1
如果两个整数e和φ(n)互质,那么一定可指定一个整数d使得ed-1被φ(n)整除,或者说ed除以φ(n)所得余数为1,此时d为e的模反元素
ed-1=kφ(n) edmolφ(n)=1 ed = 1(modφ(n))
6.公钥 kU=(e,n)
私钥 kR=(d,n)
明文 M加密 Memodn=C
密文 C解密 Cdmodn=M=(M^e mdn)^d =M^(ed) mod n= M^(kφ(n)+1)modn=(M^kφ(n),M)modn=M 即证M^kφ(n)=1
条件[a,n]互质a^φ(n)=1modn => aφ(n) = 1
import random
from random import randint
def is_prime(n):
""" 判断是否为素数 """
for i in range(2, n):
if n % i == 0:
print('此素数输入错误')
return 0
print('素数输入正确')
def create_prime(start,stop):
""" 随机生成指定范围内的素数 """
if start < 2:
start = 2
for i in range(start, stop+1):
for j in range(2, i):
if i % j == 0:
break
else:
yield i
def is_relprime(minv, maxv):
""" 判断e与oula是否互质 """
for i in range(2, minv + 1):
if minv % i == 0 and maxv % i == 0:
print('e与oula并不互为质数')
return False
print('e与oula互为质数')
return True
def compute_prikey(ol,ee):
""" 计算私钥 """
global d, k
k = 1
while (k * oula + 1) % e != 0:
k += 1
print(f'k={k}')
d = int((k * oula + 1) / e)
print(f'd={d}')
p = int(input("输入一个素数p: "))
is_prime(p)
q = int(input("再输入一个素数q: "))
is_prime(q)
n = p * q
print(f'n=p*q={n}')
oula = (p - 1) * (q - 1)
print(f'oula=(p - 1) * (q - 1)={oula}')
num=[]
for x in create_prime(0, oula):
num.append(x)
e = random.choice(num)
print(f'随机质数:e={e}')
is_relprime(e,oula)
compute_prikey(oula,e)
print(f'为你生成的公钥是:(n,e)=({n},{e})')
print(f'为你生成的私钥是:(n,d)=({n},{d})')
m = int(input("输入需要加密的数据: "))
# n = int(input("输入您的公钥前排序列: "))
# e = int(input("输入您的公钥后排序列: "))
c = (m**e)%n
print(f"您获得的密文是:{c}")
n = int(input("输入您的私钥前排序列: "))
d = int(input("输入您的私钥后排序列: "))
m = (c**d)%n
print(f'密文的解密结果为:{m}')
MD5
md5 > 哈希函数 > 消息认证
1.输入可任意长
2.输出固定长
(1)消息填充使其比特长在模512下为448
x=448mod512
560mod512=48+400(填充)
960mod512=448 差64为512倍数
(2)附加消息长度
以(1)中留出的64bit以小段方式表示消息被填充的长度,如果长大于2^64则以2^64为模数取模
(3)对MD缓冲区进行初始化
(4)以分组单位对消息进行处理