密码学加密算法合集
密码学加密算法合集
本篇整合自以下 5 篇笔记,按原发布顺序合并:
- 1. 使用base64编码加密解密
- 2. frequency_analysis(频率分析)
- 3. 使用rot13加密解密
- 4. 使用凯撒加密法进行加密解密
- 5. vigenere_cipher(维西尼亚)密码
使用base64编码加密解密
Base64编码简介
Base64这个术语最初是在“MIME内容传输编码规范”中提出的。Base64不是一种加密算法,虽然编码后的字符串看起来有点加密的赶脚。它实际上是一种“二进制到文本”的编码方法,它能够将给定的任意二进制数据转换(映射)为ASCII字符串的形式,以便在只支持文本的环境中也能够顺利地传输二进制数据。例如支持MIME的电子邮件应用,或需要在XML中存储复杂数据(例如图片)时。
要实现Base64,首先需要选取适当的64个字符组成字符集。一条通用的原则是从某种常用字符集中选取64个可打印字符,这样就能避免在传输过程中丢失数据(不可打印字符在传输过程中可能会被当做特殊字符处理,从而导致丢失)。例如,MIME的Base64实现选用了大写字母、小写字母和0~9的数字作为前62个字符。其他实现通常会沿用MIME的这种方式,而仅仅在最后2个字符上有所不同,例如UTF-7编码。
我们经常会在Base64编码字符串中看到最后有"="字符,这就是通过填充生成的。填充就是当出现编码时的情况2和3时,在后面补上"="字符,使编码后的字符数为4的倍数。
下面这段文本:
Man is distinguished, not only by his reason, but by this singular passion from other
animals, which is a lust of the mind, that by a perseverance of delight in the continued and
indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.
通过MIME Base64进行转换后就成为:
TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dC
BieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGlja
CBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZ
GVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb
24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55
IGNhcm5hbCBwbGVhc3VyZS4=
-
开发Base64的目的就不是为了加密,而是为了方便在文本环境中传输二进制数据
-
所以,与开发一个加密算法不同,安全性并不是Base64的目标,只是它的一个副产物。
实际上,Base64的安全性是非常差的,这就是在实际应用中不用它加密的原因。如果你对常用加密方法有所了解的话,你应该知道有一种古老的加密方法,称为“字符替换法”。即指定一个规则,将每个字符用其他字符替换,例如将a变为c、b变为d等,这样替换后生成的结果就是密文。解密时只需要反过来操作,将c变为a、将d变为b就可以了。用不同的替换规则加密,生成的密文也不同。
用Base64来加密实际上就相当于字符替换,只不过它先对字节做了一些变换,然后再进行替换,对加密过程来说,本质上是一样的。
字符替换法 虽然简单,但却是一个伟大的发明,它被使用了超过1千年,一直都没有有效的方法来破解它。后来人们终于发现了它的弱点:基于词频和字母频率的统计规律,就能够轻松得到它的密钥。从那以后,加密者与解密者之间的战争从来就没有停歇过,加密者不断发明更复杂更安全的加密算法,解密者则绞尽脑汁去破解它们。
喽。
代码区:
主要思想:
将信息的每一个字母抓换为ascii码,并且将所有的ascii码连接起来,补上不足的0,使得长度能被6整除,将他们以6的间距分开,将之转化为array中的字母,加上=号(是0数量的1/2)
加密与解密是相对的
使用同一数组array
array=[
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
]
加密:
'''
使用base64方式加密
'''
def encrypt_base64():
src=input("加密字符串:")
tmp = ""
result=""
eqcount=0
for char in src:
char = ord(char) #turn to the ascii
char = bin(char) #turn to the bin(二进制)
char = char.replace("0b","")
if(len(char) != 8):
char = (8-len(char))*"0"+char
tmp = tmp + char
if(len(tmp)%6!= 0):
eqcount = 6 - len(tmp)%6
tmp = tmp + (6-len(tmp)%6)*"0"
for i in range(0,len(tmp),6):
base64bin=tmp[i:i+6]
base64bin=int(base64bin,2)
result=result + array[base64bin]
result = result + int(eqcount/2)*"="
return result
运行结果

解密:
#-------------------------------------
'''
使用base64方式解密
'''
def decrypt_base64():
src=input("解密字符串")
eqcount = 0
for i in src:
if(i == "="):
eqcount=eqcount+1
src = src.replace("=",'')
tmp = ""
result = ""
for char in src:
for i in range(len(array)):
if(array[i] == char):
tmpbin=bin(i).replace("0b","")
if(len(tmpbin) !=6):
tmpbin = (6-len(tmpbin))*"0" + tmpbin
tmp = tmp + tmpbin
for i in range(0,len(tmp)-eqcount*2,8):
result=result + chr(int(tmp[i:i+8],2))
return result
运行结果

frequency_analysis(频率分析)
frequency_analysis
In cryptanalysis, frequency analysis is the study of the frequency of letters or groups of letters in a ciphertext. The method is used as an aid(0.0) to breaking classical ciphers.
Frequency analysis is based on the fact that, in any given stretch(范围) of written language, certain letters and combinations of letters occur with varying frequencies. Moreover, there is a characteristic distribution of letters that is roughly the same for almost all samples of that language. For instance, given a section of English language, E, T, A and O are the most common, while Z, Q and X are rare. Likewise, TH, ER, ON, and AN are the most common pairs of letters (termed bigrams or digraphs), and SS, EE, TT, and FF are the most common repeats. The nonsense phrase "ETAOIN SHRDLU" represents the 12 most frequent letters in typical English language text.
In some ciphers, such properties of the natural language plaintext are preserved in the ciphertext, and these patterns have the potential to be exploited in a ciphertext-only attack.
代码区:
统计:
def start():
filename=input("输入文件名称:")
print("-----文件名: "+filename+"-------")
with open(filename, 'r') as f:
file = f.read()
d={}
for i in file:
if(i.isalpha()):
if(d.get(i) == None):
d[i] = 0
d[i] = d.get(i) + 1
filename = filename+"_result"
with open(filename,"w") as f:
for k,v in d.items():
string =str(v)+" "+k+"\n" #将values写在前面有助于sort(偷懒)
f.write(string)
return "done"
使用 sort 进行排序
sort -n -r file
可以参考频率表

频率分析网站 http://www.richkni.co.uk/php/crypta/freq.php
然后猜猜猜(划重点)
然而对于我来说是太难了 0.0
毕竟母语不是英文,对单词模式没有辨识度

使用rot13加密解密
使用ROT13加密解密
ROT13(回转13位)是一种简易的替换式密码算法。它是一种在英文网络论坛用作隐藏八卦、妙句、谜题解答以及某些脏话的工具,目的是逃过版主或管理员的匆匆一瞥。ROT13 也是过去在古罗马开发的凯撒密码的一种变体。ROT13是它自身的逆反,即:要还原成原文只要使用同一算法即可得,故同样的操作可用于加密与解密。该算法并没有提供真正密码学上的保全,故它不应该被用于需要保全的用途上。它常常被当作弱加密示例的典型。
应用ROT13到一段文字上仅仅只需要检查字母顺序并取代它在13位之后的对应字母,有需要超过时则重新绕回26英文字母开头即可。A换成N、B换成O、依此类推到M换成Z,然后串行反转:N换成A、O换成B、最后Z换成M(如图所示)。只有这些出现在英文字母里的字符受影响;数字、符号、空白字符以及所有其他字符都不变。替换后的字母大小写保持不变。
代码区:
主要思想:
将所有的字符向后移动13位就行了,但要保持大写和小写
其余其他字符不变
加密与解密是相同的函数
加密与解密:
def encrypt_rot13():
src=input("输入加密字符串:")
result = ""
for x in src:
if(x.isalpha()):
if(x.isupper()):
x = ord(x)+13
if(x>90):
x=x-26
else:
x = ord(x)+13
if(x>122):
x=x-26
result = result + chr(x)
else:
result = result + x
return result
运行过程
加密

解密

linux下使用加密rot13加密解密
加密:
tr 'A-Za-z' 'N-ZA-Mn-za-m' <<< "The Quick Brown Fox Jumps Over The Lazy Dog"
解密:
echo "The Quick Brown Fox Jumps Over The Lazy Dog" |tr 'N-ZA-Mn-za-m' 'A-Za-z'
使用凯撒加密法进行加密解密
凯撒加密法
凯撒加密法,或称恺撒加密、恺撒变换、变换加密,是一种最简单且最广为人知的加密技术。
它是一种替换加密的技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。
代码区
主要思想:与rot13方式相似,向后向前偏移进行加密解密
加密
def encrypt_caesar():
shift=input("输入偏移量:")
if(not shift.isdigit()):
return "请输入数字!"
src=input("输入加密字符串:")
result = ""
for x in src:
if(x.isalpha()):
if(x.islower()):
x=x.upper()
x=ord(x)
x=x+int(shift)
if(x > 90):
x = x - 26
x = chr(x)
result = result + x
return result
运行结果

解密
def decrypt_caesar():
shift=input("输入偏移量:")
if(not shift.isdigit()):
return "请输入数字!"
src=input("输入解密字符串:")
result = ""
for x in src:
if(x.isalpha()):
if(x.isupper()):
x=x.lower()
x=ord(x)
x=x-int(shift)
if(x < 96):
x = x + 26
x = chr(x)
result = result + x
return result
运行结果

ps:
linux还可以使用tr进行解密 具体可见rot13下面

vigenere_cipher(维西尼亚)密码
Vigenere Cipher
凯撒密码
凯撒密码是一种简单的加密方法,即将文本中的每一个字符都位移相同的位置。
如选定位移3位:
原文:a b c
密文:d e f
由于出现了字母频度分析,凯撒密码变得很容易破解。
“如果我们知道一条加密信息所使用的语言,那么破译这条加密信息的方法就是找出同样的语言写的一篇其他文章,大约一页纸长,然后我们计算其中每个字母的出现频率。我们将 频率最高的字母标为1号,频率排第2的标为2号,第三标为3号,依次类推,直到数完样品文章中所有字母。然后我们观察需要破译的密文,同样分类出所有的字母,找出频率最高的字母,并全部用样本文章中最高频率的字母替换。第二高频的字母用样本中2号代替,第三则用3号替换,直到密文中所有字母均已被样本中的字母替换。” (0.0 厉害啊)
维吉尼亚密码分解后实则就是多个凯撒密码,只要知道密钥的长度,我们就可以将其分解。

如密文为:ABCDEFGHIJKLMN
如果我们知道密钥长度为3,就可将其分解为三组:
组1:A D G J N
组2:B E H K
组3:C F I M
分解后每组就是一个凯撒密码,即组内的位移量是一致的,对每一组即可用频度分析法来解密。
所以破解维吉尼亚密码的关键就是确定密钥的长度。
两种方法确定密钥的长度
一种是Kasiski测试法:确定两个相同字符串之间长度(至少为3)的公因数(目前用这个)
一种是重合指数法
定义公式:

pi(字母的出现频率--已知)

常用公式:xi为字母的频数,L为密文的长度

英语文本的重合指数为P(A)^2 + P(B)^2+……+P(Z)^2 = 0.065
利用重合指数推测密钥长度的原理在于,对于一个由凯撒密码加密的序列,由于所有字母的位移程度相同,所以密文的重合指数应等于原文语言的重合指数
假设使用维吉尼亚密码加密的密文串为y=y1y2...yn。将串y分割成m个长度相等的子串(m组),分别为y1,y2,...,ym,这样就可以以列的形式写出密文,组成一个m×(n/m)矩阵。矩阵的每一行对应于子串yi,(每一行对应一组) 1≤i≤m
如果y1,y2,...,ym按如上方式构造,则m实际上就是密钥字的长度,每一组的CI值大约为0.065。
另外,如果m不是密钥字的长度,那么子串yi看起来更为随机,因为它们是通过不同密钥以移位加密方式获得的。对于一个随机串,其重合指数为0.038 (通过猜测密钥的长度,看是否接近0.065)
在知道了密钥长度n以后,就可将密文分解为n组,每一组都是一个凯撒密码,然后对每一组用字母频度分析进行解密,和在一起就能成功解密凯撒密码
首先对子密文段重各个字母的频率进行统计(记为fi, i∈a – z),查看字母频率分布统计概率表(记pi),计算子密文段长度为n,使用公式

计算出M0,然后对子密文段移位25次,同样按照上述方法求出M1 — M25的值
根据重合指数的定义知:一个有意义的英文文本,M ≈0.065,所以找出M值接近0.065的移位数,就是秘钥中的对应字母
推荐网站 http://www.richkni.co.uk/php/crypta/vignere.php
解密很有用(0.0)
ps:
这篇文章虽然被分类到python中,但还没有用python实现 orz

浙公网安备 33010602011771号