密码学—Kasiski测试法Python程序

news2025/1/13 10:35:23

Kasiski

Kasiski是辅助破解Vigenere的前提工作,Kasiski是猜测加密者使用Vigenere密码体系的密钥的长度,Kasiski只是猜测长度而已,所以说是辅助破解Vigenere

若密文中出现两个相同的密文段(密文段的长度m>2),则它们对应的明文(及密钥)将以很大的概率相同(后文有一个该概率的计算)。
针对多表密码,首要的是得到秘钥字的长度,进一步判断密钥字的长度是否为:m=gcd(d1,d2,…,di) d:为密文片段直接的距离。
我们可以猜测秘钥字的长度m可能是d1,d2,…,di 最大公因子。
这就是Kasiski测试法。
——出自我的密码学老师PPT原文

  • 我的理解
    Kasiski的主要功劳即使帮助破解Vigenere密码找到密钥长度,具体如何找的

    • 找相同的密文片段(片段当然是两个以上才算,这个具体找多少个自己写算法的时候自己确认,或者设置一个参数手动输入)
    • 记录相同片段出现的位置(记录的是片段第一个字母出现的位置作为整个片段出现的位置)
    • 当然考虑到的肯定就是出现次数最多的了(这个算法实现还是比较费脑子)
    • 当然在找的过程中还要记录下每个出现的位置,然后用这个位置求最大公因数,那么这个最大公因数就是最有可能的密钥长度
  • 为什么最大公因数就是有可能是密钥长度
    因为在Vigenere加密中,使用的是多表加密,每一个表都是凯撒密码,使用的都是同一个字母加密,不同表只是在密钥串中的不同字母加密而已。所以假如说有相同的片段出现,就可以推断出相同密钥字母出现的周期,然后周期就是这个密钥的长度,因为Vigenere就是周期性的使用密钥对明文进行加密,下面我密码学老师的PPT对这个说法有一个很好的解释,一眼就看出是周期性的时候密钥加密。
    在这里插入图片描述
    这也很明显的点名了为啥Vigenere中要分组加密,因为分好组之后每一组第一个字母使用的都是同一个密钥加密,所以也就所谓的单表对应凯撒密码加密,Vigenere使用多个凯撒加密表。

找到出现相同片段

  • 算法实现
    • 困难:如何找到出现次数最多的片段(字母串)?
      Python真是帮了很大的一个忙了,因为有find内置函数省了我很多工作,因为只要用好下标就能够找到所有出现过的单词
    • 我的想法
      首先是传入一个字符串,然后a参数代表找的最短连续出现的片段长度,b代表最长的出现片段长度。
      为什么要这么做呢:因为如果不设置一个参数人为的介入这个程序会无限制的找下去,直到整个字符串都会find一遍,这样式毫无意义的,还很浪费性能与时间。
      由于find内置函数返回的值就是要找的片段第一个字母出现的下标,因此我甚至省去写如何找下标的步骤(在此特地感谢Python开发者们)
      • 找到下标之后我将其存进一个字典,字典的键是字符片段,值就是该片段在文本中出现的位置的各个下标,然后如果要记录出现此处就计算该列表的长度就是出现的次数了。
      • 这里我配合find内置函数采用了切片的方式进行找同片段,从给出的a参数最短的片段作为开头,那么在文本中开头0~a长度的就不用找,以此为第一个单词,然后用这个单词在后面find如果find到了表示OK找到的,存find函数返回的出现的下标,全部找完之后,使用a长度跨越a个步数,意思是这个片段已经全部找到了,往后的就是该片段之后的要重复上述操作。
      • 这里我当时想了一个我自认为很妙的方法:我遍历的是传入的ab参数,因为是人为介入的,所以我应该是从a长度的开始找,这里我的目的是给出一个步长变量step,为的就是让第二层遍历在找完某个step长的单词片段之后跨越step长度继续往后找,然后这个step还给当找到一个之后继续往后找的时候就从找到的片段的下标再加一个step然后就可以将其继续往后找,这里我认为是减少了再次遍历的次数,我个人是觉得优化了一下
      • index = mess.find(mess[i:i + step], index + 1)解读
        这个一个就是我认为写的很好的一点,mess是全部文本,首先mess[i:i+step]是表示当前要找的片段,由于是while是确保了后面会有相同片段的,然后index+1代表找第二次的时候,index已经记录第一次找到的下标,这里第二次找就是从已经找到的片段的后面找起。
def findSameWords(self, mess, a, b):
    # 找出现次数最多的字符,返回他所有下标和字符本身

    dit_wordCount = {}  # 保存不同长度的字符出现次数最多的,键:'字符',值:[出现的次数, [每次出现的下标]]

    for step in range(a, b + 1):
        for i in range(len(mess) - step):
            # 每一次进入if都是全局搜索,如果之前判断过存放在字典中没有该字符串就继续全局文本中去find
            if mess[i:i + step] not in dit_wordCount.keys():
                ''' 
                    意思是mess从step+i开始找有没有和mess[i:i+step]该字符串相同的字符串
                    同时保证了i是递增,并且mess截串是从一开始的下标0开始找,
                    整个mess文本里面又是从i+step开始往后findmess截串
                    ↓ 
                '''
                #这里是先试探一下是否存在,存在就做初始化操作,否则-1的话就不用继续进入
                index = mess.find(mess[i:i + step], i + step) 
                if index != -1: dit_wordCount[mess[i:i + step]] = [1, [i + 1]]  # 当该字符不止出现一次的时候就初始化该字符的字典键
                while index != -1:  # 找到了
                    dit_wordCount[mess[i:i + step]][0] += 1
                    dit_wordCount[mess[i:i + step]][1].append(index + 1)
                    index = mess.find(mess[i:i + step], index + 1)  # 继续找
    return dit_wordCount

找到相同长度不同片段中出现次数最多的片段

  • 解释:这里使用的是上面存的字典,然后进行这下面的操作

在这里说的是找到相同长度片段中出现次数最多的,意思就是在一篇文本中相同片段的很多,然后片段长度相同的也很多,这里要找的就是从这些不同片段但是长度相同的片段中找到频率最多的,这里就相当于打擂台操作了。
然后由于字典中已经完成了大部分工作,在这一步中只需要将其遍历然后将所需的数据放进另一个字典中即可。
在本步骤中要找的数据:[(片段, [出现次数,[每次出现的下标]]) , … ]

  • 第一步是先统计每个片段出现频率并找出最大的那个(这里会出现很多,因此需要有之后的第二步)
    代码如下:满满的注释,感谢自己。
 def caltFrequence(self, dit_wordCount):
     selectWord = []  # 保存挑选出来符合条件的单词
     last_len = 0  # 字典中字符串长度相同中最后一个 ,用于保存每一次循环中字符长度,利用字符长度改变来判断是否进行完成一轮该字符长度的筛选操作
     maxcount = 0  # 该字符长度的字典里面出现最大次数
     temp = None
     for item in dit_wordCount.items():  # 感谢开发者们让字典从Python3.6版本开始变得可以有顺序了,节省了我写代码再次区分字符串长度不同的
         if len(item[0]) > last_len and temp != None and self.sb_MaxKeyCurrtime.value() <= temp[1][0]:
             # 判断是否在该字符长度内出现次数最多,比如字符串长度为3中,出现次数最多的为CHR那么该字符就保存下来,其他就丢掉
             # len(item[0]) > last_len 假如字符串长度发生变化就表示进入了下一个不同的字符串长度的域,需要把上一个temp存下来的数据加进去
             # temp != None判断是否是第一次进入
             # self.sb_MaxKeyCurrtime.value() <= temp[1][0]控制至少出现的次数
             selectWord.append(temp)
         if item[1][0] > maxcount and len(item[0]) == last_len or len(item[0]) > last_len:
             # 假如该item中出现次数比之前相同字符的还要多,就存入该字符的数据 。
             # len(item[0]) > last_len控制是否是字符长度有所改变,或者是否是第一次进入
             last_len = len(item[0])
             maxcount = item[1][0]
             temp = item

     # print(selectWord)
     return selectWord
     # 每一项的结构就是: [('CHR', [5,    [1, 166, 236, 276, 286] ]  ),......]
     #                   字符  出现次数   对应字符在密文中出现的下标位置

  • 第二步
    我是通过一个类中一个变量接收的猜测的最长长度
  • 可能会有疑惑:刚刚不是找最短出现的次数吗,现在怎么又是最长了。
    当我们在最短中往后找的时候,可能会出现很长的出现片段,由于我们找的不仅仅是一个长度的片段的,我还找了其他不同长度的片段,那么就可能会导致找到一个很长的,但同时又满足最短出现的次数,然后又是在该片段中相同长度的不同片段中出现的次数最多,那么就是属于符合条件的了。
    那么在这一步中就是人为的介入,将认为没有必要的比如:很长一段片段,然后出现次数刚好满足最短的出现次数,并且你觉得我们的加密方没有闲到用这么长的密钥加密的时候你就可以切除掉这个隐患。

代码如下:

def getMaxNumList(self, selectData):  # 每一项的结构就是: [('CHR', [5,    [1, 166, 236, 276, 286] ]  ),......]
    # num_list = []
    keymaxlen = self.sb_choiceMaxKeylen.value()  # 允许猜测密钥的最长长度,也就是最大公因数
    ch_maxnum = []
    for item in selectData:
        # 拆包,提取出计算最大公因数的距离数字
        ch, date = item
        count, index_list = date
        # if self.sb_MaxKeyCurrtime.value() > count-1: continue
        print(index_list)
        distance_list = []
        for j in range(len(index_list) - 1):
            distance_list.append(index_list[j + 1] - index_list[0])
        num = distance_list[0]
        for j in range(1, len(distance_list)):
            num = math.gcd(num, distance_list[j])
        # num_list.append(num)
        if num > keymaxlen:
            selectData.remove(item)
        else:
            ch_maxnum.append([ch, num])
    return ch_maxnum

到这一步Kasiski测试法基本就结束了,测试法顾名思义测试的,还不是很有力的证据,因此在这里使用的定义仅仅是找到出现次数最多的相同片段然后将其位置下标做一个gcd求最大公因数即猜测为密钥长度(如果是很普通的明文与密钥加密的Vigenere一般到这一步基本可以确认长度了),如果是一篇很乱的,基本没有出现重复的或者很短一篇文章这个测试法就很局限了,很容易就失效的一个方法,而且出现的频次相同但是计算出来的gcd不同更难搞,因为密钥长度这时候就有两种方案了
如果说有两种方案的密钥猜测出来,这时候就需要另一个方法了,那就是计算重合指数(这个重合指数靠的纯纯是已知的一般文章中的字母概率进行统计,但是对于一般的但是有两种密钥方案的就可以很好的区分出到底哪一个更接近真实的密钥长度。)
所以Kasiski测试法测试出来的长度是否真的是密钥长度还需要重合指数来进一步验证

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/693749.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetcode第66题:加一

题目 这是一道简单的小题&#xff0c;自己却也没写出来。。。逆序遍历数组digits&#xff0c;用carry标记当前元素是否需要进位&#xff08;0不要&#xff0c;1要&#xff09;。 若carry1&#xff0c;则当前元素要么置0&#xff0c;要么自加1。自加1之后&#xff0c;再也不需要…

【深入了解Spring Cloud Alibaba Nacos:服务注册和配置中心】—— 每天一点小知识

&#x1f4a7; 深入了解 S p r i n g C l o u d A l i b a b a N a c o s &#xff1a;服务注册和配置中心 \color{#FF1493}{深入了解Spring Cloud Alibaba Nacos&#xff1a;服务注册和配置中心} 深入了解SpringCloudAlibabaNacos&#xff1a;服务注册和配置中心&#x1f4a7;…

深入浅出解析LoRA完整核心基础知识 | 【算法兵器谱】

Rocky Ding 公众号&#xff1a;WeThinkIn 写在前面 【算法兵器谱】栏目专注分享AI行业中的前沿/经典/必备的模型&论文&#xff0c;并对具备划时代意义的模型&论文进行全方位系统的解析&#xff0c;比如Rocky之前出品的爆款文章Make YOLO Great Again系列。也欢迎大家提…

让Ai帮我们画个粽子,它会画成什么样呢?

让Ai帮我们画个粽子&#xff0c;它会画成什么样呢&#xff1f; 本文目录&#xff1a; 一、Ai绘图技术的现状 二、看看Ai理解的粽子是怎样的 2.1、基础粽子 2.2、生成不同风格的粽子 2.2.1、真实风格的粽子 2.2.2、插图风格的粽子 2.2.3、3D风格的粽子 2.2.4、卡通风格…

Mysql锁机制介绍

Mysql锁机制 锁是计算机协调多个进程或线程并发访问某一资源的机制。 在数据库中&#xff0c;除传统的计算资源(如CPU、RAM、I/O等)的争用以外&#xff0c;数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题&#xff0…

vue-cli笔记

vue的生命周期&#xff1a; 借鉴react 钩子函数&#xff1a; change() 挂载完毕&#xff0c;vue完成模板解析&#xff0c;并把初始的真实的dom元素放入到页面后执行 beforeCreate() {// 数据代理和数据监测创建之前console.log(beforeCreate) }, created() {console.l…

深度:全面解析数据智能的金融“炼金术”!

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 金融以其财富效应&#xff0c;成为最新科技的试金石。一项新技术出来后&#xff0c;人们首先闪过的念头就是“能不能用它赚钱”。例如&#xff0c;ChatGPT带火了大模型&#xff0c;人们也开始将目标聚焦到大模型在金融领域的…

【实战】 JWT、用户认证与异步请求(下) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(五)

文章目录 一、项目起航&#xff1a;项目初始化与配置二、React 与 Hook 应用&#xff1a;实现项目列表三、TS 应用&#xff1a;JS神助攻 - 强类型四、JWT、用户认证与异步请求1~56.用useAuth切换登录与非登录状态7.用fetch抽象通用HTTP请求方法&#xff0c;增强通用性8.用useHt…

AR宇航员互动体验软件:虚拟与现实叠加增强体验感

随着科技的不断发展&#xff0c;人们对太空探索的兴趣和热情也越来越高涨。为了满足人们对太空探索的渴望&#xff0c;广州华锐互动研发了宇航员AR模拟体验软件&#xff0c;这种软件可以让用户身临其境地体验太空探索的过程&#xff0c;提供一种全新的、令人兴奋的太空探索新体…

css基础知识十一:CSS3新增了哪些新特性?

一、是什么 css&#xff0c;即层叠样式表&#xff08;Cascading Style Sheets&#xff09;的简称&#xff0c;是一种标记语言&#xff0c;由浏览器解释执行用来使页面变得更为美观 css3是css的最新标准&#xff0c;是向后兼容的&#xff0c;CSS1/2的特性在CSS3 里都是可以使用…

图解CNN中的卷积(卷积运算、池化、Padding、多通道的卷积)

文章目录 卷积操作池化Padding对多通道&#xff08;channels&#xff09;图片的卷积套上激活函数是什么样的参考&#xff1a; 卷积层是深度学习神经网络中经常使用的一种层。它通过卷积运算来提取输入的特征&#xff0c;常用于图像、语音等信号处理任务中。 卷积层有以下几个参…

rocketmq-spring-boot-starter支持SpringBoot 1.x(spring-context 4.x)版本

1 问题说明 由于历史原因&#xff0c;项目使用的是SpringBoot1.x版本&#xff0c;而且由于种种原因&#xff0c;不能升级。在项目开发迭代过程中&#xff0c;决定使用RocketMQ作为消息中间件&#xff0c;因为是SpringBoot项目&#xff0c;理所应当的引入了rocketmq-spring-boo…

简单聊聊数字孪生与GIS融合的必要性

随着科技的不断发展和应用的不断深入&#xff0c;数字孪生和GIS在各自领域中展现出巨大的潜力。然而&#xff0c;更引人注目的是&#xff0c;数字孪生和GIS的融合将为许多行业带来全新的机遇和变革。在本文中&#xff0c;我们将探讨数字孪生和GIS融合的必要性&#xff0c;以及它…

2023ty计网期末综合题满分冲刺版

1. 假设有段1km长的CSMA/CD网络链路的数据传输率为1Gb/s。设信号在此链路媒介上的传播速度为2x105 km/s&#xff0c;求使用此协议的最短数据帧长度。 &#xff08;1&#xff09;传播时延&#xff1a;1/2000005微秒&#xff0c; &#xff08;2&#xff09;往返时延&#xff1a…

List合并的操作

List合并的操作 1.addAll方法 List list1new ArrayList();List list2new ArrayList();for (int i 0; i < 10; i) {list1.add(i*2);list2.add(i*21);}System.out.println(list1);//方法1&#xff1a;addAlllist1.addAll(list2);System.out.println(list1); 2.Stream操作 L…

ATTCK(二)之ATTCK的发展历史

ATT&CK的发展历史 MITRE公司 MITRE是美国NIST标准化组织选择的专注于网络安全的组织&#xff0c;由美国联邦政府资助。很多安全标准都MITRE制定的&#xff0c;比如有名的漏洞CVE编号规则以及威胁情报格式STIX。所以ATT&CK非常有影响力&#xff0c;而且未来能成为一个公…

MySQL----MHA高可用

文章目录 一、MHA理论1.1什么是 MHA1.2MHA 的组成1.3MHA 的特点 二、MHA的一主两从部署实验设计故障修复步骤&#xff1a; 一、MHA理论 1.1什么是 MHA MHA&#xff08;MasterHigh Availability&#xff09;是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。 MHA 的出…

Java 日志重点梳理

大家好&#xff01;我是今越。重点梳理一下在 Java 程序开发中关于日志管理的知识点&#xff0c;以及在 Spring Boot 框架中该如何使用日志。 在 Java 中&#xff0c;日志框架主要分为两大类&#xff1a;日志门面和日志实现。 日志门面 日志门面定义了一组日志的接口规范&am…

LangChain-Agent自定义Tools类 ——输入参数篇(二)

给自定义函数传入输入参数&#xff0c;分别有single-input 参数函数案例和multi-input 参数函数案例&#xff1a; from langchain.agents import Tool from langchain.tools import BaseTool from math import pi from typing import Union from math import pi from typing …

StringBuffer和正则表达式

StringBuffe 获取int类型的最大值和最小值 System.out.println(Integer.MAX_VALUE);//int类型的最大值 System.out.println(Integer.MIN_VALUE);//int类型的最小值输出结果 Integer和String相互转换 Integer i1 new Integer(100); System.out.println(i1);Integer i2 new…