1.编码
编码就是将一个对象映射为比特序列。因为在计算机中,文字、图片等都是0、1即比特序列存储的。
比如ASCII编码:一个字符映射为一个字节(8bit)
控制字符:
可显示字符:
python实现文本按照ASCII编码映射为比特序列:
#! /usr/bin/env python3
def char2bin(text):
'''将给定文本(仅可显示字符)转换按ASCII编码转换成比特序列'''
res = ''
for char in text:
res += '0'+bin(ord(char))[2:]
return res
if __name__ == '__main__':
text = 'UsernameandPassword'
print(char2bin(text))
结果如下:
01010101011100110110010101110010011011100110000101101101011001010110000101101110011001000101000001100001011100110111001101110111011011110111001001100100
#! /usr/bin/env python3
def bin2char(sequence):
'''将给定比特序列(仅可显示字符)按ASCII编码转换成文本'''
res = ''
for i in range(len(str(sequence))//8):
res += chr(int('0b'+sequence[8*i:8*i+8],2))
return res
if __name__ == '__main__':
seq = '0101010101110011011001010111001001101110011' \
'0000101101101011001010110000101101110011001' \
'0001010000011000010111001101110011011101110' \
'11011110111001001100100'
print(bin2char(seq))
结果如下:
UsernameandPassword
2.XOR运算
XOR运算即异或运算(Exclusive or)
运算规则是:
- 1 + 1 = 0
- 1 + 0 = 1
- 0 + 1 = 1
- 0 + 0 = 0
#! /usr/bin/env python3
def xor(seq1,seq2):
'''对两个相同长度比特序列进行XOR运算'''
seq1 = str(seq1)
seq2 = str(seq2)
if len(seq1) != len(seq2):
raise Exception('lengths of two sequences must be the same')
else:
res = ''
for i in range(len(seq1)):
if seq1[i] != seq2[i]:
res += '1'
else:
res += '0'
return res
if __name__ == '__main__':
seq1 = '0101010110101010100010'
seq2 = '1000001010111101001011'
print(xor(seq1,seq2))
结果如下:
1101011100010111101001
3.一次性密码本 one-time-pad
一次性密码本加密就是将明文的比特序列和随机生成的比特序列进行XOR运算
#!/usr/bin/env python3
import random
from char2bin import char2bin
from bin2char import bin2char
from xor import xor
def randomSequence(n=10):
'''生成给定长度的比特序列 默认长度为10'''
res = ''
for i in range(n):
res += str(random.randint(0,1))
return res
if __name__ == '__main__':
text = 'UsernameAndPassword'#原文本
seq1 = char2bin(text)#原比特序列
print(seq1)
seq2 = randomSequence(len(text)*8)#随机比特序列
print(seq2)
seq = xor(seq1,seq2)#一次性密码本加密后的比特序列
print(seq)
res = bin2char(seq)#密文
print(text,'\n',res)#打印明文和密文
res2 = bin2char(xor(seq,seq2))#将密文再次和随机比特序列进行运算
print(res2)
结果如下:
01010101011100110110010101110010011011100110000101101101011001010100000101101110011001000101000001100001011100110111001101110111011011110111001001100100
01001111011011000011100001011011101101010001001001110011011110000000110110011110110011011001000100010010111100101100100101110010101101000101100001000001
00011010000111110101110100101001110110110111001100011110000111010100110011110000101010011100000101110011100000011011101000000101110110110010101000100101
UsernameAndPassword
])ÛsLð©ÁsºÛ*%
UsernameAndPassword
理论上一次性密码本是无法破译的
- 一是密钥空间太大,为 2n 这里写图片描述
- 二是即使计算机有能力遍历密钥空间,但是遍历的同时,解密之后会出现任何可能的明文,我们无法判断这是否就是加密前的明文
4.为什么一次性密码没有在现实中大量使用?
- 密钥配送:密钥配送过程中可能被窃取
- 密钥保存:密钥长度随明文长度增加而增加
- 密钥重用:一次性密钥不方便重用,因为一旦密钥泄露,之前用该密钥加密的密文都将被解密(如果之前的密文被窃取的话)
- 密钥同步:加入明文有100M大小,那么密钥长度也有100M,增加了通信成本,且比特序列不允许错位
- 密钥生成:密钥是通过伪随机数生成器生成的,并不是真正的随机数