趣味密码学入门–cryptohack
前言
Awesome CTF中发现了一个有趣的密码学挑战平台–cryptohack,小白的我通过做题来学习密码学知识吧
cryptohack平台官网:https://cryptohack.org/
cryptohack平台的题目几乎都是Python3编写,题目类型有三个:
- 下载易受攻击的源代码并确定如何破解输出。
- 向服务器发出Web请求并缓慢提取机密数据。
- 连接到端口,并对试图进行通信的两方进行中间人攻击。
由此,通过做题熟悉python相关密码库的应用及密码学知识
题目面板如下,本篇文章介绍INTRODUCTION/GENERAL基础内容
注意:由于平台公告超过10分以上的题目题解不允许发送到公网,以打码来处理~
INTRODUCTION
包含三个入门级别的挑战来帮助我们了解解题的基本方法和提交flag
Finding Flags
每个题目都要求我们找到一个“flag”,将flag提交到题目下方的表单中,即可完成此题。若flag正确会提示"You have solved this challenge!"
Great Snakes
下载并运行"great_snakes.py"
提交flag,得到"You have solved this challenge!"
Network Attacks
根据题目介绍,本题使用中间人攻击的方式获取flag。使用telnetlib库对socket.cryptohack.org 11112端口已JSON对象的方式进行请求,下载样例telnetlib_example.py
#!/usr/bin/env python3
import telnetlib
import json
HOST = "socket.cryptohack.org"
PORT = 11112
tn = telnetlib.Telnet(HOST, PORT)
def readline():
return tn.read_until(b"\n")
def json_recv():
line = readline()
return json.loads(line.decode())
def json_send(hsh):
request = json.dumps(hsh).encode()
tn.write(request)
print(readline())
print(readline())
print(readline())
print(readline())
request = {
"buy": "clothes" # clothes--> flag
}
json_send(request)
response = json_recv()
print(response)
将clothes改为flag,即可拿到flag
GENERAL
学习现代密码学之前的基础知识,相关在线工具都可以使用,这里使用python3进行解题
ENCODING
ASCII
ord = [99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125]
print(''.join(chr(o) for o in ord))
Hex
有时候我们加密之后的密文包含不可见的ASCII字符,为了更加方便的分享密文,通常使用HEX编码以便适配不同的操作系统
from binascii import a2b_hex,unhexlify
# binascii模块包含很多转换二进制和各种ASCII编码的二进制表示法
# binascii.a2b_hex(hexstr) 和binascii.unhexlify(hexstr):从十六进制字符串hexstr返回二进制数据
h = '63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d'
print(a2b_hex(h))
# print(unhexlify(h))
拿到flag
Base64
Base64编码也是非常常见的一种编码方式,以64个字符组成的ASCII字符串来表示二进制数据。其中Base64中的字符编码6位,4个字符编码为3个字节
from binascii import a2b_hex,unhexlify # binascii模块包含很多用来方法来转换二进制和各种ASCII编码的二进制表示法
import base64
h = '72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf'
print(a2b_hex(h)) # hex --> bytes
print(base64.b64encode(a2b_hex(h))) # 进行一波base64编码
print(base64.encodebytes(a2b_hex(h)).decode('utf-8')) # bytes --> str
Bytes and Big Integers
类似于RSA的加密算法通常作用于数字,但我们通常需要加密的信息是一段字符串,那么我们如何将信息转化为数字来进行算法加密呢?
通常的方法是将消息以字节为顺序转为十六进制,依次进行连接,同样也可以使用base16/base10来表示,示例如下:
message: HELLO
ascii bytes: [72, 69, 76, 76, 79]
hex bytes: [0x48, 0x45, 0x4c, 0x4c, 0x4f]
base-16: 0x48454c4c4f
base-10: 310400273487
from Crypto.Util.number import long_to_bytes
# PyCryptodo