mt19937 伪随机数算法加密以及解密

mt19937 伪随机数算法加密以及解密一、简介mt19937算法是梅森旋转算法(MersenneTwister)的变体,是一个伪随机数发生算法,可以产生32位整数序列。具有以下的优点二、代码实现32位的MT19937的python代码如下:def_int32(x):returnint(0xFFFFFFFF&x

大家好,欢迎来到IT知识分享网。

一、简介

mt19937算法是梅森旋转算法(Mersenne Twister)的变体,是一个伪随机数发生算法,可以产生32位整数序列。具有以下的优点
 
mt19937 伪随机数算法加密以及解密0
 

二、代码实现

32位的MT19937的python代码如下:
def _int32(x):
    return int(0xFFFFFFFF & x)

class MT19937:
    # 根据seed初始化624的state
    def __init__(self, seed):
        self.mt = [0] * 624
        self.mt[0] = seed
        self.mti = 0
        for i in range(1, 624):
            self.mt[i] = _int32(1812433253 * (self.mt[i - 1] ^ self.mt[i - 1] >> 30) + i)

    # 提取伪随机数
    def extract_number(self):
        if self.mti == 0:
            self.twist()
        y = self.mt[self.mti]
        y = y ^ y >> 11
        y = y ^ y << 7 & 2636928640
        y = y ^ y << 15 & 4022730752
        y = y ^ y >> 18
        self.mti = (self.mti + 1) % 624
        return _int32(y)

    # 对状态进行旋转
    def twist(self):
        for i in range(0, 624):
            y = _int32((self.mt[i] & 0x80000000) + (self.mt[(i + 1) % 624] & 0x7fffffff))
            self.mt[i] = (y >> 1) ^ self.mt[(i + 397) % 624]

            if y % 2 != 0:
                self.mt[i] = self.mt[i] ^ 0x9908b0df

三、例题

以昨天打的DASCTF10月赛为例
pycode
阅读pyc字节码后的加密算法如下
def extract_number(x):
    x = x ^ (x >> 11)
    x = ((x << 7) & 2022072721) ^ x
    x = ((x << 15) & 2323163360) ^ x
    x = (x >> 18) ^ x
    return x

def transform(m):
    new_message = b""
    l = len(m)
    for i in range(l//4):
        enc = m[i * 4 : i*4+4]
        enc = number.bytes_to_long(enc)
        enc = extract_number(enc)
        enc = number.long_to_bytes(enc,4)
        new_message += enc

#flag提交格式为DASCTF{账号+密码}
enc = '8b2e4e858126bc8478d6a6a485215f03'
num = input('input your number:')
tmp = bytes.fromhex(num)
res = hex(transform(tmp))

if enc == res:
    print(f"ok,your flag : DASCTF\{{num\}}")
else:
    print("wrong")

那么我们有

1、解法一

使得明文通过不断的加密最后还是明文
from Crypto.Random import random
from Crypto.Util import number

def extract_number(x):
    x = x ^ (x >> 11)
    x = ((x << 7) & 2022072721) ^ x
    x = ((x << 15) & 2323163360) ^ x
    x = (x >> 18) ^ x
    return x

def transform(message):
    assert len(message) % 4 == 0
    new_message = b''
    for i in range(len(message) // 4):
        block = message[i * 4 : i * 4 +4]
        block = number.bytes_to_long(block)
        block = extract_number(block)
        block = number.long_to_bytes(block, 4)
        new_message += block
    return new_message
def circle(m):
    t=m
    while True:
        x=t
        t=transform(t)
        if t==m:
            return x
transformed_flag='8b2e4e858126bc8478d6a6a485215f03'
flag = circle(bytes.fromhex(transformed_flag)).hex()
print('transformed_flag:', flag)


# DASCTF{89196e63ab5556e7389d2bb44f8e6e06}

2、解法二

逆向 extract_number函数
# 解法二
from Crypto.Util import number

# right shift inverse
def inverse_right(res, shift, bits=32):
    tmp = res
    for i in range(bits // shift):
        tmp = res ^ tmp >> shift
    return tmp


# right shift with mask inverse
def inverse_right_mask(res, shift, mask, bits=32):
    tmp = res
    for i in range(bits // shift):
        tmp = res ^ tmp >> shift & mask
    return tmp

# left shift inverse
def inverse_left(res, shift, bits=32):
    tmp = res
    for i in range(bits // shift):
        tmp = res ^ tmp << shift
    return tmp


# left shift with mask inverse
def inverse_left_mask(res, shift, mask, bits=32):
    tmp = res
    for i in range(bits // shift):
        tmp = res ^ tmp << shift & mask
    return tmp

# def extract_number(x):
#   x = x ^ (x >> 11)
#   x = ((x << 7) & 2022072721) ^ x
#   x = ((x << 15) & 2323163360) ^ x
#   x = (x >> 18) ^ x
#   return x

def convert(y):
    y = inverse_right(y,18)
    y = inverse_left_mask(y,15, 2323163360)
    y = inverse_left_mask(y,7,2022072721)
    y = inverse_right(y,11)
    return y&0xffffffff

def transform(message):
    assert len(message) % 4 == 0
    new_message = b''
    for i in range(len(message) // 4):
        block = message[i * 4 : i * 4 +4]
        block = number.bytes_to_long(block)
        block = convert(block)
        block = number.long_to_bytes(block, 4)
        new_message += block
    return new_message

transformed_flag = '8b2e4e858126bc8478d6a6a485215f03'
c = bytes.fromhex(transformed_flag)
flag = transform(c)
print (flag.hex())

 

 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/30690.html

(0)

相关推荐

发表回复

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

关注微信