[BSidesSF2020]decrypto-1

本文介绍了基于科克霍夫斯原理的加密系统,并提供了一个Python实现的加密代码示例。该代码使用了一次一密的加密方法,并结合了SHA256哈希和JSON序列化。解题过程展示了如何通过分析代码和解密过程找到密钥,最终解密出隐藏的flag。
摘要由CSDN通过智能技术生成

[BSidesSF2020]decrypto-1

题目

Kerckhoffs’s principle states that “A cryptosystem should be secure even if everything about the system, except the key, is public knowledge.” So here’s our unbreakable cipher.

import sys
import json
import hashlib


class Crypto:

    def __init__(self, key):
        if not isinstance(key, bytes):
            raise TypeError('key must be of type bytes!')
        self.key = key
        self._buf = bytes()
        self._out = open("/dev/stdout", "wb")

    def _extend_buf(self):
        self._buf += self.key

    def get_bytes(self, nbytes):
        while len(self._buf) < nbytes:
            self._extend_buf()
        ret, self._buf = self._buf[:nbytes], self._buf[nbytes:]
        return ret

    def encrypt(self, buf):
        if not isinstance(buf, bytes):
            raise TypeError('buf must be of type bytes!')
        stream = self.get_bytes(len(buf))
        return bytes(a ^ b for a, b in zip(buf, stream))

    def set_outfile(self, fname):
        self._out = open(fname, "wb")

    def encrypt_file(self, fname):
        buf = open(fname, "rb").read()
        self._out.write(self.encrypt(buf))


class JSONCrypto(Crypto):

    def encrypt_file(self, fname):
        buf = open(fname, "r").read().strip()
        h = hashlib.sha256(buf.encode('utf-8')).hexdigest()
        data = {
                "filename": fname,
                "hash": h,
                "plaintext": buf,
        }
        outbuf = json.dumps(data, sort_keys=True, indent=4)
        self._out.write(self.encrypt(outbuf.encode("utf-8")))


def main(argv):
    if len(argv) not in (3, 4):
        print("%s <key> <infile> [outfile]" % sys.argv[0])
        return
    argv.pop(0)
    key = argv.pop(0)
    inf = argv.pop(0)
    crypter = JSONCrypto(key.encode("utf-8"))
    if sys.argv:
        crypter.set_outfile(argv.pop(0))
    crypter.encrypt_file(inf)


if __name__ == '__main__':
    main(sys.argv)

flag.txt.enc

:TL\Z\QETVRQ
SIH fGNV\\\ETV[UVQU
] 	A_]UC^	QWZC _RY@QYRU_[@^^[CfGNVDQ
]	U@VE-d2OM N8
_@boFbC	1SMM[L:	

解题
科克霍夫斯原理声明“密码系统应该是安全的,即使系统的所有内容,除了密钥,都是公共知识。”所以这里是我们的牢不可破的密码。

牢不可破的密码,那就可能是一次一密了。

先读程序:

sys.argv[]是一个从程序外部获取参数的桥梁,因为我们从外部取得的参数可以是多个,所以获得的是一个列表,也就是说sys.argv其实可以看作是一个列表,所以才能用[]提取其中的元素。其第一个元素是程序本身,sys.argv[0]表示代码本身文件路径,随后才依次是外部给予的参数。

pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。

hash.hexdigest() 返回摘要,作为十六进制数据字符串值。

json.dumps()将一个Python数据结构转换为JSON对象,indent:参数根据数据格式缩进显示,读起来更加清晰,skipkeys:默认值是False,如果dict的keys内的数据不是python的基本类型(str,unicode,int,long,float,bool,None),设置为False时,就会报TypeError的错误。此时设置成True,则会跳过这类key 。

解题代码:

import json
data = {
                "filename": 'flag.txt',
                "hash": 'h',

        }
outbuf = json.dumps(data, sort_keys=True, indent=4)
cipher_pre=open('flag.txt.enc','rb').read()
for i in range(43):
    print(chr(cipher_pre[i]^ord(outbuf[i])))
    #得到key
key='n0t4=l4g'
for i in range(8):
    key+=key
    #使key足够长.
flag=''
for i in range(len(cipher_pre)):
    flag+=chr(ord(key[i])^cipher_pre[i])
print(flag)

运行得到:

{
    "filename": "flag.txt",
    "hash": "2f98b8afa014bf955533a3e72cee0417413ff744e25f2b5b5838f5741cd69547",
    "plaintext": "CTF{plz_dont_r0ll_ur_own_crypto}"
}

答案

flag{plz_dont_r0ll_ur_own_crypto}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值