古典密码-置换密码

凯撒密码能使用的密钥数取决于字典的大小,因此可以即为轻松的破解密码。相对于凯撒密码而言,置换密码则包含了更多的可能密钥数,因此破解难度更大。

置换密码又称为换位密码,这种密码通过改变明文消息各元素的相对位置来进行加密。置换密码包含许多种不同的类型,包括铁路围栏密码、路线密码、Myszkowski置换密码和终端置换密码等。本文以一种简单的置换密码-柱形置换密码为例,讲解该种加密的原理和破解方法。

章节:

  1. 置换密码加密原理
  2. 置换密码解密原理
  3. 置换密码破解原理
  4. 置换密码加解密代码+应用
  5. 置换密码破解代码+应用

1.置换密码加密原理

置换密码主要是通过对明文中的字符重新排列进行加密,从而使得密文变得不可读。使用置换密码进行加密的步骤如下:

  • 计算明文和密钥字符的个数
  • 绘制密钥数的列
  • 使用明文中的字符,包括符号、空格、标点等,从左到右开始对列进行填充
  • 当列被填满,并且明文还有剩余字符时,则另起一行进行填充
  • 当明文中字符都被填充完后,若当前行中仍有列未被填充,则用纯黑(标识作用,符号不限)填充。
  • 从被填充完毕的行列矩阵的左上方开始,从上往下从左到右的顺序读取字符。即当读取到一列底部时,移到右侧列的最上方继续读取字符,读取的过程中跳过纯黑项。

最终读取出的字符串便是密文。

例如,现有明文如下,算上空格和标点,该段明文共19个字符。(艾欧尼亚昂扬不灭!)

ionia still stands!

使用柱状置换密码对上述明文进行加密,密钥选择为6,加密过程如下:

(1)计算明文和密钥字符的个数

被加密的明文共19个字符。

(2)绘制密钥数的列

密钥为6,因此绘制6个列,如下:

(3)使用明文的字符进行填充

按照顺序将明文中的字符填充到第一行中,如下:

(4)填充完所有明文中的字符

明文仍有剩余字符则另起一行,直到明文中所有字符都填充完毕,如下:

(5)用纯黑标识未被填充的列

如下:

(5)读取密文

从上列矩阵的左上方开始,从上往下,从左到右的顺序读取字符,注意跳过被黑色标识的项。

  • 第一列中可读取到字符串:iss!
  • 第二列中可读取到字符串:ott
  • 第三列中可读取到字符串:nia
  • 第四列中可读取到字符串:iln
  • 第五列中可读取到字符串:ald
  • 第六列中可读取到字符串:  s(注意字符s之前还包含了两个空白字符)

将所有列读取到的字符串进行拼接,最终的密文如下。需要注意的是密文中包含了两个空白字符。

iss!ottniailnald  s

2.置换密码解密原理

柱形置换密码的解密流程如下:

  • 用密文长度除以密钥长度,将结果向上取整,得到列数
  • 绘制行数为密钥、列数为上一步计算结果的矩阵
  • 用网格总数减去密文长度,得到被黑色填充的项数
  • 在最右侧的列中,从下往上填充黑色,数目为上一步计算的结果
  • 将密文中的字符,从左到右、从上往下填充表格,注意跳过被黑色填充的项
  • 从矩阵的左上方开始,从上往下、从左到右的读取字符,从而得到明文

对于如下密文,算上空格和标点,该段密文共19个字符。

iss!ottniailnald  s

密钥为6,对上述密文进行解密,解密过程如下:

(1)计算列数

密文长度除以密钥长度,结果向上取整计算列数如下:

[19 ÷ 6 = 4]

(2)画出转换矩阵

列数为4,行数为6,转换矩阵如下:

(3)计算黑色数量

矩阵中网格总数减去密文字符数得到需要填充的黑色的数量,如下:

4 × 6 – 19 = 5

(4)填充黑色

在最右侧列中,从下往上填充第三步计算结果(5)数量的黑色。

(5)填充密文字符

将密文中的字符,从左到右、从上往下填充表格,注意跳过被黑色填充的项。

(6)读取明文

从左上角开始,从上往下、从左到右的顺序读取字符。

  • 第一列可读取到字符串:ionia (结尾处存在一个空白字符)
  • 第二列可读取到字符串:still (结尾处存在一个空白字符)
  • 第三列可读取到字符串:stands
  • 第四列可读取到字符串:!

将所有列读取到的字符进行拼接,得到解密后的明文为:

ionia still stands!

3.置换密码破解原理

置换密码相较于凯撒密码来说,虽然增加了密钥的可能数量,但是其密钥数不会大于明文的一半,通过计算机暴力破解的方法仍旧可以很快的破解置换加密的密文(思考为什么密钥数通常不会大于明文的一半)。

由于凯撒密码的密钥数很少,在破解凯撒密码时,我们通过人为观察的方式来确定真正的密钥。这种观察的方法并不适合置换密码破解,因此在爆破时,我们将使用程序替代人眼来判断爆破出的明文是否为可阅读的明文。

4.置换密码加解密代码+应用

置换密码加密函数如下:

def transpositionEncrypt(text="",key=1):
    """[置换密码加密函数]
    Args:
        text (str, optional): [明文].
        key (int, optional): [密钥].
    """ 
    # 密钥不能小于1
    if key < 1:
        key = 1
    # 存储密文,共key个列
    cipherText = ['']*key
    # 按列填入密文
    for itemColumn in range(key):
        # 字符下标,初始为当前的列号
        currentColumn = itemColumn
        # 当下标小于明文长度,继续在当前列中填入密文
        while currentColumn < len(text):
            # 在当前列中添加下标为currentColumn的字符
            cipherText[itemColumn] += text[currentColumn]
            # 下标增加key值
            currentColumn += key
    # 返回密文
    return (''.join(cipherText))
0/21/0 懂得都懂

置换密码解密函数如下:

def transpositionDecrypt(text = "",key = 1):
    """[置换密码解密函数]
    Args:
        text (str, optional): [密文].
        key (int, optional): [密钥].
    """
    # 密钥不能小于1
    if key < 1:
        key = 1
    # 列数。密文长度除以密钥,结果向上取整
    numOfColumns = math.ceil(len(text) / key)
    # 行数
    numOfRows = key
    # 黑色标识项的数量
    numOfShadedBoxes = (numOfColumns * numOfRows) - len(text)
    # 存储明文
    plainText = [""] * numOfColumns
    column = 0
    row = 0
    # 遍历密文中每个字符
    for item in text:
        # 将字符填充到列
        plainText[column] += item
        # 填充完一个字符后,列+1,满足从左到右的顺序
        column += 1
        # 如果超过列数,或遇到黑色标注的区域,则列重置为0、行+1,表示换行
        if(column == numOfColumns) or (column == numOfColumns -1 and row>=numOfRows - numOfShadedBoxes):
            column = 0
            row += 1
    # 返回解密后的明文
    return (''.join(plainText))
0/21/0 懂得都懂

5.置换密码破解代码+应用

置换密码破解函数如下:

# 破解函数
def transpositionHacker(text):
    # 遍历密文长度个密钥
    for itemKey in range(1,len(text)):
        # 当前密钥进行解密
        itemPliantText = transpositionDecrypt(text,itemKey)
        # 解密后的明文中英文单词数大于%50,则输出密钥和解密后的明文
        checkScore = checkEn(itemPliantText)
        if checkScore> 0.5:
            print("\n分数:{}\nkey:{}\n解密:{}".format(checkScore,itemKey,itemPliantText))
    print("破解结束!")

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注