BUAA^AITMCLab2021级Lab1题解

Lab1题解

一、关于Lab1.py提供的加密过程分析

  • 可以注意到明文(message,也就是flag)被隐藏,初始化的密文需要我们逆推得出
message = '*****{********************}'
cipher = ''
  • Lab1采用的加密方式是移位密码
    • 关于移位密码:

​ 其加密变换为:
E k ( m ) = ( m + k )   m o d   q = c 0 ≤ m ,   c < q E_k(m) = (m+k)~mod~q = c\\ 0 \leq m,~cEk(m)=(m+k) mod q=c0m, c<q
密钥空间 K = { k ∣ 0 ≤ k < q } K=\{k|0\leq kK={k∣0k<q} ,元素个数为q,当 k = 0 k=0 k=0 时,为恒等变换

​ 其解密变换为:
D k ( c ) = ( c − k )   m o d   q = m D_k(c)=(c-k)~mod~q=m Dk(c)=(ck) mod q=m

key, _, _ = xgcd(24249125136394343, 16156191447296617)
key = key % 16156191447296617 
  • key实为24249125136394343的逆元,可以采用扩展欧式算法得出

    • 关于逆元:

      设n为正整数,a为整数满足 0 < a < n 00<a<n

      若存在一个正整数b, 0 < b < n 00<b<n 满足:
      a b ( m o d   n ) = 1 ab(mod~n)=1 ab(mod n)=1
      称b为 a ( m o d   n ) a(mod~n) a(mod n) 的逆元,并记b为 a − 1 ( m o d   n ) a^{-1}(mod~n) a1(mod n)

    • 关于逆元使用扩欧算法计算:

      若想求得满足 a x ( m o d   n ) = 1 的逆元 x ,等价于 ax(mod~n)=1的逆元x,等价于 ax(mod n)=1的逆元x,等价于 a x = k n + 1 , k ax=kn+1,k ax=kn+1k 为整数

      移项得 a x − k n = 1 ax-kn=1 axkn=1
      a x + l n = 1 ax+ln=1 ax+ln=1
      可以发现求解逆元转化为扩欧算法计算x,但x可能为负,所以再次取模保证了 k e y > 0 key>0 key>0 (这是因为python的模运算会保证非负)

      更多内容详见:https://zhuanlan.zhihu.com/p/449221995

  • 关于扩欧算法:

    • 关于AITMCLAB.libnum中所带扩欧算法函数,可直接import使用,其实现可自行查看

      def xgcd(a, b):
          """
          Extented Euclid GCD algorithm.
          Return (x, y, g) : a * x + b * y = gcd(a, b) = g.
          """
          pass
      
    • 关于自己编写的Egcd()函数

      def Egcd(a, b):
          x = [a, 1, 0]
          y = [b, 0, 1]
          while y[0] != 0:
              q = x[0]//y[0]
              for i in range(0, 3):
                  x[i] = x[i] - q*y[i]
              tmp = x[:]
              x = y[:]
              y = tmp[:]
          return x
      

      个人关于扩欧算法的理解:使用单位阵 I I I 将辗转相除法每一步所等价的初等矩阵 P i P_i Pi(左乘)的结果 P = P 1 P 2 . . . P t P=P_1P_2...P_t P=P1P2...Pt记录下来
      [ a 1 0 b 0 1 ] − > [ r u v 0 m n ] 其中  P = [ u v m n ] \left[\begin{matrix} a&1&0\\ b&0&1 \end{matrix}\right] -> \left[\begin{matrix} r&u&v\\ 0&m&n \end{matrix}\right] \\其中~P= \left[\begin{matrix} u&v\\ m&n \end{matrix}\right] [ab1001]>[r0umvn]其中 P=[umvn]

    • 移位加密程序实现:

      for char in message:
          if 'a' <= char <= 'z':
              now_cipher = (ord(char) - ord('a') + key) % 26
              cipher += chr(now_cipher + ord('a'))
          else:
              cipher += char
      
  • 最后再一次使用逆元进行计算(同key)得到了output

    numOfCipher = s2n(cipher)
    bigPrime = 356591097085378373041406631775396675403608993465904761745667548546613469964055945893375233
    output, _, _ = xgcd(numOfCipher, bigPrime)
    output = output % bigPrime 
    # output = 233238587670647787805028809001128036933176275182381815462045390514627843647184629262585311
    

二、关于Lab1的解密过程

核心任务在于:

  1. 如何实现移位密码的解密变换
  2. 如何求解numOfCipher
  • 一些库函数导入和已知的数据
from AITMCLAB.libnum import n2s, s2n, xgcd
bigPrime = 356591097085378373041406631775396675403608993465904761745667548546613469964055945893375233
output = 268287563061576100897937311713001449077245433065661668430027784938038192146644112389472865
key, _, _ = xgcd(24249125136394343, 16156191447296617)
key = key % 16156191447296617  # 取正的余数
# key为24249125136394343的逆元
# (ppx, ppy, gcd) = (-5984828584066420, 8982739386836133, 1)
# key = 10171362863230197
  • 关于实现移位密码的解密变换
def decode(cpr):
    msg = ""
    for c in cpr:
        if 'a' <= c <= 'z':
            now_msg = c - ord('a')
            msg += chr(((now_msg - key) % 26) + ord('a'))
        else:
            msg += chr(c)
    return msg
  • 关于numOfCipher的求解
    • 回忆扩欧算法

a x + b y = 1 ax+by=1 ax+by=1

​ 加密时使用numOfCipher(a)bigPrime(b)得到output(x):
n u m O f C i p h e r   ∗   o u t p u t   +   b i g P r i m e   ∗   y = 1 numOfCipher~*~output~+~bigPrime~*~y=1 numOfCipher  output + bigPrime  y=1
​ 反之,解密时使用output(a)bigPrime(b)得到numOfCipher:
o u t p u t   ∗   n u m O f C i p h e r   +   b i g P r i m e   ∗   y = 1 output~*~numOfCipher~+~bigPrime~*~y=1 output  numOfCipher + bigPrime  y=1

noc, _, _ = xgcd(output, bigPrime)
noc = noc % bigPrime
  • 最后使用n2s将cipher复原,并解码
    • 注意n2s返回的字符串为字节数据类型,形如: b ′ h e l l o _ w o r l d ′ b'hello\_world' bhello_world,所以需要转换为utf-8的编码,再使用decode进行解密变换
cipher = n2s(noc)
cipher = cipher.decode("utf-8")
message = decode(cipher)

你可能感兴趣的:(python,网络安全)