目录
  1. 1. 仿射密码
    1. 1.1. 原理
      1. 1.1.1. 加密函数
      2. 1.1.2. 解密函数
      3. 1.1.3. 举例说明
    2. 1.2. 看到的一些解密思路
仿射密码

仿射密码

原理

仿射密码是一种表单代换密码,字母表的每个字母相应的值使用一个简单的数学函数对应一个数值,再把对应数值转换成字母。

图

加密函数

E(x)=(ax+b)(modm)

注意:
x表示明文按照某种编码得到的数字;
a和 m互质;
m是编码系统中字母的个数(通常都是26)。

看到以上加密形式,可以进一步推测是否为仿射加密

解密函数

D(x)=a−1(x−b)(modm)

注意:
a−1 是 a 在 Zm群的乘法逆元
  • 这里先附上乘法逆元的相关脚本:

    #欧几里德算法求最大公约数
    def get_gcd(a, b):
        k = a // b
        remainder = a % b
        while remainder != 0:
            a = b 
            b = remainder
            k = a // b
            remainder = a % b
        return b
    
    #改进欧几里得算法求线性方程的x与y
    def get_(a, b):
        if b == 0:
            return 1, 0
        else:
            k = a // b
            remainder = a % b        
            x1, y1 = get_(b, remainder)
            x, y = y1, x1 - k * y1            
        return x, y
    
    a = input('a:')
    b = input('b:')
    a, b = int(a), int(b)
    
    #将初始b的绝对值进行保存
    if b < 0:
        m = abs(b)
    else:
        m = b
    flag = get_gcd(a, b)
    
    #判断最大公约数是否为1,若不是则没有逆元
    if flag == 1:    
        x, y = get_(a, b)    
        x0 = x % m #对于Python '%'就是求模运算,因此不需要'+m'
        print("所求的逆元:",x0) #x0就是所求的逆元
    else:
        print("Do not have!")

举例说明

我们以 E(x)=(5x+8) mod 26函数为例子进行介绍,加密字符串为 AFFINECIPHER,这里我们直接采用字母表26个字母作为编码系统

图

密文就是IHHWVCSWFRCP。

解密过程:

先求解5关于模26的乘法逆元,为21
解密函数就是D(x) = 21(x - 8) mod 26 

解密如下图:

图

解密脚本:

#仿射密码解密
#改进欧几里得算法求线性方程的x与y
def get(a, b):
    if b == 0:
        return 1, 0
    else:
        k = a //b
        remainder = a % b
        x1, y1 = get(b, remainder)
        x, y =y1, x1 - k * y1
    return x, y

s = input("请输入解密字符:").upper()
a = int(input("请输入a:"))
b = int(input("请输入b:"))

#求a关于26的乘法逆元
x, y = get(a, 26)
a1 = x % 26

l= len(s)
for i in range(l):
    cipher = a1 * (ord(s[i])- 65 - b) % 26
    res=chr(cipher + 65)
    print(res, end='')

得到:

图


看到的一些解密思路

我们可以看到的是,仿射密码对于任意两个不同的字母,其最后得到的密文必然不一样,所以其也具有最通用的特点。当密文长度足够长时,我们可以使用频率分析的方法来解决。

其次,我们可以考虑如何攻击该密码。可以看出当a=1时,仿射加密是凯撒加密。而一般来说,我们利用仿射密码时,其字符集都用的是字母表,一般只有26个字母,而不大于26的与26互素的个数一共有

ϕ(26)=ϕ(2)×ϕ(13)=12

算上b的偏移可能,一共有可能的密钥空间大小也就是

12×26=312

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

这种密码由两种参数来控制,如果我们知道其中任意一个参数,那我们便可以很容易地快速枚举另外一个参数得到答案。

但是,假设我们已经知道采用的字母集,这里假设为26个字母,我们还有另外一种解密方式,我们只需要知道两个加密后的字母 y1,y2 。即可进行解密。

那么我们还可以知道

y1=(ax1+b)(mod26)y2=(ax2+b)(mod26)

两式相减,可得

y1−y2=a(x1−x2)(mod26)

这里 y1,y2已知

如果我们知道密文对应的两个不一样的字符 x1 与 x2 ,那么我们就可以很容易得到 a ,进而就可以得到 b 了。

文章作者: Sakura式
文章链接: http://yoursite.com/2020/07/31/%E4%BB%BF%E5%B0%84%E5%AF%86%E7%A0%81/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hexo
打赏
  • 微信
  • 支付寶