专栏首页网络攻防实战知识交流nuca_crypto_babycrypto_writeup

nuca_crypto_babycrypto_writeup

#coding:utf_8
import gmpy2 as gm

c = ''  #太长了不写了

best_index_of_Coincidence = 0.065

best_freq = {}
best_freq['a'] = 0.08167
best_freq['b'] = 0.01492
best_freq['c'] = 0.02782
best_freq['d'] = 0.04253
best_freq['e'] = 0.12702
best_freq['f'] = 0.02228
best_freq['g'] = 0.02015
best_freq['h'] = 0.06094
best_freq['i'] = 0.06966
best_freq['j'] = 0.00153
best_freq['k'] = 0.00772
best_freq['l'] = 0.04025
best_freq['m'] = 0.02406
best_freq['n'] = 0.06749
best_freq['o'] = 0.07507
best_freq['p'] = 0.01929
best_freq['q'] = 0.00095
best_freq['r'] = 0.05987
best_freq['s'] = 0.06327
best_freq['t'] = 0.09056
best_freq['u'] = 0.02758
best_freq['v'] = 0.00978
best_freq['w'] = 0.02360
best_freq['x'] = 0.00150
best_freq['y'] = 0.01974
best_freq['z'] = 0.00074

print best_freq


def index_of_coincidence(s):
    '''
    计算字符串s的重合指数,即所有字符出现概率的平方和
    :param s:密文字符串
    :return:s的重合指数
    '''
    zimubiao = 'abcdefghijklmnopqrstuvwxyz'
    freq = {}
    for x in zimubiao:
        freq[x] = 0
    for x in s:
        freq[x] = freq[x] + 1
    index = 0
    for x in zimubiao:
        # index = index + pow(float(freq[x]) / len(s), 2)
       index = index + float(freq[x] * (freq[x] - 1)) / (len(s) * (len(s) - 1))
    return index


def index_of_coincidence_2(s):
    '''
    计算明文s的拟重合指数,即s中字母的频率与英文字母的统计规律吻合程度
    :param s:解出的明文
    :return:s的拟重合指数
    '''
    zimubiao = 'abcdefghijklmnopqrstuvwxyz'
    freq = {}
    for x in zimubiao:
       freq[x] = 0
    for x in s:
        freq[x] = freq[x] + 1
    index = 0
    for x in zimubiao:
        index = index + float(freq[x]) / len(s) * best_freq[x]
    return index


def guessMN():
    '''
    根据题意,该加密应当会周期使用密钥,该周期是key_a长度和key_k长度的最小公倍数。
    遍历周期1到100,分别测试不同周期下各个子密文段的重合指数,然后求平均
    :return:无返回值,打印出所有与最佳重合指数相差小于0.01的周期
    '''
    for l in range(1, 100):
        avergage_index = 0
        for i in range(l):
            s = ''.join([c[j * l + i] for j in range(0, len(c) / l)])
            index = index_of_coincidence(s)
            avergage_index += index

        avergage_index = avergage_index / l - best_index_of_Coincidence
        if abs(avergage_index) < 0.01:
            print 'l=', l
            print avergage_index

    print '开始猜测周期'
    guessMN()#结果显示,重合指数得分较高的都是6的整数倍,所以周期极有可能是6

    l = 6



def decryptChar(c, i, j):
    '''
    对单个密文字符解密。
    :param c: 单个密文字符
    :param i: 与字符c相乘的那个密钥
    :param j: 用于位移的密钥
    :return: 明文字符
    '''
    i_inv = gm.invert(i, 26)
    p = chr((ord(c) - ord('a') - j) * i_inv % 26 + ord('a'))
    return p


def decrypt(s, i, j):
    '''
    用固定的i和j,解密子密文段
   :param s: 使用相同i和j加密的子密文段
    :param i: 与字符c相乘的那个密钥
   :param j: 用于位移的密钥
    :return: 明文字符串
    '''
    p = ''
    for c in s:
        p += decryptChar(c, i, j)
    return p


def guessKey(c):
    '''
   对子密文段爆破它所使用的i和j
    :param c: 子密文段
    :return: 无返回值,但是打印拟重合指数最佳的i和j,即解出的明文统计规律与英文字符统计规律最吻合的i和j
    '''
    for i in range(26):
        if i % 2 == 0 or i == 13: #若i与26不互素,则解除的明文不唯一,所以i一定不是2和13的倍数
            continue
        for j in range(26):
            s = decrypt(c, i, j)
            # print s
            index = index_of_coincidence_2(s)
            index = abs(index - 0.065)
            if index < 0.01:
                print i, j, index

def guessAllKeys():
    '''
   以l为周期,将完整密文c切分成l个子密文段,对这l个子密文段分别爆破其所使用密钥i和j
    :return: 无返回值,但打印出最佳的密钥组合
    '''
    for i in range(l):
        s = ''.join([c[j * l + i] for j in range(0, len(c) / l)])
        print i
        guessKey(s)

print '开始猜测密钥组合'
guessAllKeys()
# 根据打印结果,发现最佳组合依次是
# 19,10
# 7,9
# 23,3
# 19,24
# 7,14
# 23,15
# 将l设置成12、18、24或更多,还是可以得到这样的组合的重复
# 现在基本可以确定密钥应该是这样的
key_a = [19, 7, 23]
key_k = [10, 9, 3, 24, 14, 15]

#利用key_a, key_k解密完整的密文,得到明文
p = ''
for i in range(len(c)):
    p += decryptChar(c[i], key_a[i % 3], key_k[i % 6])
print p
# 明文.......flagishelloxnucagoodluck
# 末尾是flagishelloxnucagoodluck
# 由此可得falg:helloxnucagoodluck

本文分享自微信公众号 - 无级安全(wujisec),作者:某大师傅

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-11-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 强网杯线下Web签到和CVE-2019-9081

    强网杯有一个web题目 序列化getshell 算是签到题目laravel-5.7rce首先先搭建环境

    用户5878089
  • 破解Charles

    由于Charles是使用java这种弱语言编写的,即使加了各种混淆,但是也难逃被破解的命运! 官网上下载的只能免费使用30天

    用户5878089
  • MetInfo 6.0.0反馈管理页面存储XSS(CVE-2018-7721)分析

    说明:MetInfo 6.0.0中的跨站点脚本(XSS)漏洞允许远程攻击者注入任意Web脚本或HTML

    用户5878089
  • 微信小程序入门《二》实例:条件渲染、数据遍历、网络请求、获取本地图片

    实例内容 条件渲染 数据遍历 网络请求 获取本地图片 实例一: 条件渲染 如果motto为Hello World,则输出你好世界,否则原样输出。 这里是分支条件...

    极乐君
  • 鼓舞士气,5种线上活动让员工“燃”起来!

    讲真,乐乐一直都很佩服我们公司的HR小姐姐们 ? 现在不提倡线下聚集、团建,她们脑暴的线上趣味活动那是一个接一个~ 确实,我们前几期推送了如何让员工在特殊时期...

    腾讯乐享
  • 网络排错大盘点

    为什么要先讲必备条件?因为这里所讲的网络排错并不仅仅是停留在某一个小小命令的使用上,而是一套系统的方法,如果没有这些条件,我真的不能保证下面讲的这些你可以听得懂...

    杰哥的IT之旅
  • 实现三遍决策树,你就会想出更快的算法!

    背景 决策树(Decision Tree)可以说是当下使用最为广泛的机器学习模型,任何一个刚刚学习人工智能或者数据挖掘的同学可能都接触过实现决策树的课程作业。 ...

    企鹅号小编
  • 动态 | 百度宣布陆奇辞去集团总裁兼COO,留任副董事长

    昱良
  • [Leetcode][位运算]相关题目汇总/分析/总结

    后端技术漫谈
  • 【重磅】陆奇去向终落定:担任YC中国创始人兼CEO!

    【新智元导读】今天,陆奇宣布成为Y Combinator中国创始人及首席执行官,并担任Y Combinator全球研究院院长。陆奇去哪儿终于有了答案。

    新智元

扫码关注云+社区

领取腾讯云代金券