密码学课程设计之仿射加密

时间:2024-05-21 07:00:46

前言

终于放假了,整理一波之前密码学的报告和笔记;

正文

简述

仿射密码,是古典密码里面比较经典的替换密码,在我看来就是将移位密码和数乘密码结合到了一起;

加密方程:C=(k1*M+k2)mod26

解密方程:M=(C-k2)*(k1^-1)mod26

其中k1必须与26互素,这样才可以产生k1的逆元用于解密;没有对k1的限制,可能无法解密。

代码分析

加密算法

这里的p为需要加密的明文,k1,k2就是上述的两个**,先看明文需要加密几个字母,有几个字母就产生几轮循环,每次循环将字母先转换为0~25的数字,然后进行数乘和移位变换,然后再转换为字符,存储在一个字符变量c中,直到循环结束为止,这就得到了密文;

#仿射加密
def fangshe(p,k1,k2):
	c=""
	for i in range(len(p)):
		temp=chr((((ord(p[i])-ord('a'))*k1+k2)%26)+ord('a'))
		c+=temp
	return c

判断最大公因数

如果需要解密,则必须要使得k1能够产生对26的逆元,即要使k1和26互素,所以判断k1和26是否最大公约数为1;

#判断最大公因数
def gcd(x,y):
	if x>y:
		temp=y
	else:
		temp=x
	for i in range(1,temp+1):
		if((x%i==0) and (y%i==0)):
			s=i
	return s

解密算法

解密首先要判断k1和26是否互素,互素才可以解密,在互素的前提下计算k1对于26的逆元:k1_re,然后用解密放生进行循环解密即可输出明文;

#仿射解密
def decode(a,b,str1):
	c1=""
	if(gcd(a,26)==1):
		for i in range(26):
			if((a*i)%26==1):
				k1_re=i
				break
		for i in range(len(str1)):
			temp=chr((((ord(str1[i])-ord('a'))-b)*k1_re)%26+ord('a'))
			c1+=temp
		return c1

完整代码

刚写python,比较丑…

# -*- coding: utf-8 -*-
#仿射加密
def fangshe(p,k1,k2):
	c=""
	for i in range(len(p)):
		temp=chr((((ord(p[i])-ord('a'))*k1+k2)%26)+ord('a'))
		c+=temp
	return c
#判断最大公因数
def gcd(x,y):
	if x>y:
		temp=y
	else:
		temp=x
	for i in range(1,temp+1):
		if((x%i==0) and (y%i==0)):
			s=i
	return s
#仿射解密
def decode(a,b,str1):
	c1=""
	if(gcd(a,26)==1):
		for i in range(26):
			if((a*i)%26==1):
				k1_re=i
				break
		for i in range(len(str1)):
			temp=chr((((ord(str1[i])-ord('a'))-b)*k1_re)%26+ord('a'))
			c1+=temp
		return c1
    
def main():
	print 8*"*"+" EncryptInput "+8*"*"
	p=raw_input("Please enter the plain:")
	k1=input("Please enter k1:")
	k2=input("Please enter k2:")
	print 8*"*"+" Encryption "+8*"*"
	c=fangshe(p,k1,k2)
	print ("Cipher:"+c)
	print "\n"+8*"*"+" DecryptInput "+8*"*"
	C=raw_input("Please enter the Cipher:")
	key1=input("Please enter k1:")
	key2=input("Please enter k2:")
	print 8*"*"+" Decryption "+8*"*"
	plain=decode(key1,key2,C)
	print "Plain:"+plain
    
if __name__ == '__main__':
	main()

运行结果及正确性

输入明文hellocumt,k1=7,k2=2加密所得的密文用仿射解密得出原来的明文,所以正确性得到验证

密码学课程设计之仿射加密

安全性分析

1.仿射密码对于任意两个不同的字母,其最后得到的密文肯定不一样;所以当密文长度足够长时,我们可以使用频率分析的方法来解决。利用仿射密码时,一般只有 26 个字母,而不大于 26 的与 26 互素的个数一共有12个,算上偏移量,也就是大概12x26=312种可能性。

一般来说,对于该种密码,至少得是在已知部分明文的情况下才可以攻击。下面进行简单的分析。

已知部分明密文对:y1=(ax1+b)mod26 y2=(ax2+b)(mod26)

两式相减:y1−y2=a(x1−x2)(mod26)很容易得到a,得到了a即可解出b

2.对密文直接用312个**空间进行暴破,脚本如下:

#coding:utf-8
plain="zebbwqmif"
c=""
k=[1,3,5,7,9,11,15,17,19,21,23,25]
for i in range(12):
	for j in range(26):
		c=""
		for x in range(len(plain)):
			res=chr((ord(plain[x])-ord('a')-j)*k[i]%26+ord('a'))
			c+=res
		print c#+'\n'
		if c=="hellocumt":
			print 8*"*"+"find it"+8*"*"

运行结果:找到有意义的密文

密码学课程设计之仿射加密