这个是老师布置的额外作业,emmm就随便发发咯

简单的随机数生成工具

  • 1707170129 李思琪 2020-05-20

结构:

  • 前端界面:MDUI + jQuery
  • 后端处理:Apache + PHP
  • 随机生成:Python 3.6

网址:https://www.dmantick.tk/tools/


原理流程:

  • 密钥初始化:
    • [密钥KEY1]:根据服务器当前内存使用率(精确至48位小数)、CPU数据的C64编码值的生成sha256值(结果取128bit);
    • [密钥KEY2]:获取当前时间戳与[密钥KEY1]的C64编码值的生成的sha256值(结果取128bit);
    • [不变密钥KEY]:16384位RSA中P和Q乘积生成的sha256值(结果取128bit);
    * 使用者可以随时通过向服务器发送请求,来实时生成[密钥KEY1]以及[密钥KEY2]的值,不变密钥则由服务器秘密保存。
    *注:本文所有提到的C64并非CRC-64算法。

  • 随机字节流生成操作:
    • [第一步]:先生成2048位的RSA,取其两个质数 P 和 Q,以及乘积 N 值;
    • [第二步]:使用[密钥KEY2]作为AES128密钥,输入值为 P 的sha256值的base64编码,之后取AES128加密结果的128bit(奇数次加密取前128bit,偶数次加密为后128bit)与前 1 次加密时使用的密钥异或的结果作为当前加密密钥,加密所得的结果的sha256值的base64编码作为当前需要加密的值,一共轮代 5 次;
    • [第三步]:获取使用者发送请求的时间戳以及当前加密时的时间戳的base64编码,以[不变密钥KEY]进行AES128加密,之后取 Q 和 前 1 次加密使用的密钥异或的结果作为当前加密密钥,加密所得的结果的sha256值的base64编码作为当前需要加密的值,一共轮代 5 次;
    • [第四步]:将[第二步]和[第三步]所得的结果异或,然后将异或所得的结果的base64编码以 P 和 Q,进行RSA2048的加密;
    • [第五步]:将[第四步]所得的结果分别取前一半和后一半的sha256值,以及所得结果和 N 的或的sha256值,以[前一半的sha256值] + [所得结果和 N 的或的sha256值] + [后一半的sha256值] 组成结果作为随机字节流;
    * 由于sha256所得的hash值有浮动,所得随机字节流结果于 95 ~ 96字节之间,也就是一次最多能生成 90+ 的任意随机字符。

  • 原理图示:

    • image-20200520154230399.png


生成随机字节流的各个算法代码实现:

  • 主要用到算法:C64|BASE64|AES128|RSA|SHA256
  • C64(这个是我基于BASE64编码算法简单写的一个转码算法= =,本初是为了隐藏WEB的反弹shell弹回来的IP和端口):
    '''
    @Description: C64
    @Author: DQ
    @LastEditors  : DQ
    @Date: 2020-05-03 13:09:11
    @LastEditTime : 2020-05-18 10:33:59
    '''
    
    # 简单的变种base64算法
    # 若需转码数据字节的2进制流为6的倍数,则比base64多长1位;其余情况,均比base64少1位
    # 局限是转码最小单位为字节,小于1个字节的数据流得补0
    # 简单的替换表,可以随意改变,其实也可以当成一个简单的密钥
    C64_TABLE = [
        '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x20',
        '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', '\x28', '\x29', '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39', '\x40', '\x41', '\x42', '\x43',
        '\x44', '\x45', '\x46', '\x47', '\x48', '\x49', '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', '\x58', '\x59', '\x60', '\x61', '\x62', '\x63'
    ]
    
    
    def encrypt( s: str ):
        # 先将每个字节转换成8位的2进制模式
        bits = "".join(bin(byte)[ 2: ].zfill(8) for byte in bytes(s.encode('gbk')))[ ::-1 ]
        length = len(bits)
    
    
        # 然后进行(所转换成2进制位数长度 - 1)的循环(1个字节=8长,循环 8 - 1 = 7 次)
        for count in range(length - 1):
            #	具体算法为:当前位置值 和 后 1 位值的异或(迭代进行)
            #	比如 1011 那么步骤为
            #	取[10]11,1 ^ 0 = 1 => 1011,
            #	取1[01]1,0 ^ 1 = 1 => 1111,
            #	取11[11],1 ^ 1 = 0 => 1101,
            # 	但这并非最终结果,仅是一个例子,结果会受到下一步操作的影响
    
            bits = bits[ :count ] + str(int(bits[ count ]) ^ int(bits[ count + 1 ])) + bits[ count + 1: ]
    
            # 每次异或完毕后,进行11次循环,每次循环步骤为
            # 先右循环移1位,然后倒置
    
            for i in range(11):
                bits = (bits[ -1 ] + bits[ :-1 ])[ ::-1 ]
    
        # 先取得到的2进制流的奇位和偶位
        # 公式为:奇数位组成值的前一半长 + 偶数位组成值 ^ 奇数组成位值 + 奇数位组成值后一半长
        left = ""
        right = ""
        for i in range(length):
            if (not i % 2):
                left += bits[ i ]
            else:
                right += bits[ i ]
        data = right[ :len(right) // 2 ] + "".join(
            str(int(byte1) ^ int(byte2)) for byte1, byte2 in zip(left, right)) + right[ len(right) // 2: ]
    
        # 取得结果的2进制流模6值,若不足6位则补值6位,若正好为6位则多补6位
        # 比如 24->30 32->36
        data = data + "".join(str(byte % 2) for byte in range(6 - len(data) % 6))
    
        # 根据替换表进行替换
        result = "".join(C64_TABLE[ int(data[ i * 6:(i + 1) * 6 ], 2) ] for i in range(len(data) // 6))
    
        return result
    
    
    # 解码的话,倒回去即可
    def decrypt( s: str ):
        data = "".join(bin(C64_TABLE.index(font))[ 2: ].zfill(6) for font in s)
        data = data[ :-(len(data) % 8) ]
        data_len = len(data)
    
        right = data[ :data_len // 4 ] + data[ -data_len // 4: ]
        left = "".join(str(int(byte1) ^ int(byte2)) for byte1, byte2 in zip(data[ data_len // 4:data_len // 4 * 3 ], right))
        bits = ""
    
        for i in range(data_len):
            if (not i % 2):
                bits += left[ i // 2 ]
            else:
                bits += right[ i // 2 ]
    
        for count in range(data_len - 1, 0, -1):
            for i in range(11):
                bits = bits[ ::-1 ]
                bits = (bits[ 1: ] + bits[ 0 ])
            bits = bits[ :count - 1 ] + str(int(bits[ count ]) ^ int(bits[ count - 1 ])) + bits[ count: ]
        bits = bits[ ::-1 ]
        result = "".join(chr(int(bits[ x * 8:(x + 1) * 8 ], 2)) for x in range(len(bits) // 8)).encode("latin1").decode(
            'gbk')
    
        return result
    
    
    if __name__ == '__main__':
        while True:
            try:
    
                en = encrypt(input("input:"))
                print("Encrypt: ", en)
    
                de = decrypt(en)
                print("Decrypt:", de)
            except KeyboardInterrupt:
                break
    

  • BASE64:
    '''
    @Description: Base64
    @Author: DQ
    @LastEditors  : DQ
    @Date: 2020-01-04 14:55:52
    @LastEditTime : 2020-01-04 22:05:46
    '''
    
    # base64编码表
    base64_dict = { 0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E', 5: 'F', 6: 'G', 7: 'H', 8: 'I', 9: 'J',
                    10: 'K', 11: 'L', 12: 'M', 13: 'N', 14: 'O', 15: 'P', 16: 'Q', 17: 'R', 18: 'S',
                    19: 'T', 20: 'U', 21: 'V', 22: 'W', 23: 'X', 24: 'Y', 25: 'Z', 26: 'a', 27: 'b',
                    28: 'c', 29: 'd', 30: 'e', 31: 'f', 32: 'g', 33: 'h', 34: 'i', 35: 'j', 36: 'k',
                    37: 'l', 38: 'm', 39: 'n', 40: 'o', 41: 'p', 42: 'q', 43: 'r', 44: 's', 45: 't',
                    46: 'u', 47: 'v', 48: 'w', 49: 'x', 50: 'y', 51: 'z', 52: '0', 53: '1', 54: '2',
                    55: '3', 56: '4', 57: '5', 58: '6', 59: '7', 60: '8', 61: '9', 62: '+', 63: '/' }
    
    # base64编码逆表
    base64_reverse_dict = { 'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8, 'J': 9,
                            'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15, 'Q': 16, 'R': 17, 'S': 18,
                            'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23, 'Y': 24, 'Z': 25, 'a': 26, 'b': 27,
                            'c': 28, 'd': 29, 'e': 30, 'f': 31, 'g': 32, 'h': 33, 'i': 34, 'j': 35, 'k': 36,
                            'l': 37, 'm': 38, 'n': 39, 'o': 40, 'p': 41, 'q': 42, 'r': 43, 's': 44, 't': 45,
                            'u': 46, 'v': 47, 'w': 48, 'x': 49, 'y': 50, 'z': 51, '0': 52, '1': 53, '2': 54,
                            '3': 55, '4': 56, '5': 57, '6': 58, '7': 59, '8': 60, '9': 61, '+': 62, '/': 63 }
    
    
    # base64转码
    def enb64( source, enbytes = True ):
        try:
            data = source.encode( )  # 预处理将传入值转为2进制流
        except AttributeError:
            data = source
        length = len(data)  # 获取需转码的值的总长度
        end = length % 3  # 获取补位数
        out = ""  # 预设输出变量
        equal = ""  # 预设输出补位
        if (end != 0):  # 若补位数不为0则计算需要进行的补位各个量
            tmp = ""
            for _ in range(3 - end):
                tmp += "\x00"
                equal += "="
            data += bytes(tmp.encode( ))  # 进行补位(\x00)
            length += 3 - end  # 刷新补位后的总长度
        for part in range(length // 3):  # 以每3个字节为1组进行操作
            bins = ""
            for byte in range(3):
                bins += "%08d" % int(bin(data[ part * 3 + byte ])[ 2: ])  # 将每3个字节分解成 3 * 8 共 24 个bit
    
            for byte in range(4):
                out += base64_dict[ int(bins[ byte * 6:(byte + 1) * 6 ], 2) ]  # 从上边24个bit中每6个bit的数值索引base64编码
        if (end != 0):  # 若补位数不为0则在结果后边补上对应数量的"="
            out = (out[ :(-1) * (3 - end) ] + equal)
        if (enbytes):  # 判断是否需要将结果转为2进制流
            out = out.encode( )
        return out  # 输出结果
    
    
    # base64解码
    def deb64( source, debytes = True ):
        try:
            data = source.decode( )  # 预处理将传入值进行2进制流解码
        except AttributeError:
            data = source
        length = len(data)  # 计算总长
        equaln = length % 4  # 若长度不正确自动补"="
        for _ in range(equaln):  # 补"="
            data += "="
        end = data.count("=")  # 计算"="的数量
        out = bytes( )  # 预设输出变量
        data = data.replace("=", "A")  # 将补位符"="转换成"A"(000000)以好做解码处理
        for part in range(length // 4):  # 以每4个字符1组进行解码
            bins = ""
            for each in range(4):
                bins += "%06d" % int(
                    bin(base64_reverse_dict[ data[ part * 4 + each ] ])[ 2: ])  # 将组中每个字符经过base64编码逆表得到的数值重组回24bit
    
            for each in range(3):
                out += bytes(chr(int(bins[ each * 8:(each + 1) * 8 ], 2)).encode("latin1"))  # 将得到的24bit重组回 3 * 8 模式的3个字节
        if (end != 0):  # 若存在补位则将后边补位的"\x00"去除
            out = out[ :(-1) * end ]
        if (not debytes):  # 判断是否将二进制流结果解码
            out = out.decode( )
        return out  # 输出结果
    
    if __name__ == '__main__':
        pass

  • AES128:
    '''
    @Description: AES128
    @Author: DQ
    @LastEditors  : DQ
    @Date: 2020-03-14 21:16:22
    @LastEditTime : 2020-03-15 01:52:14
    '''
    
    import b64, re, functools
    
    
    class AES_128(object):
    
        def __init__( self ):
    
            # 声明正S盒
            self.S_box = [
                [ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 ],
                [ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 ],
                [ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 ],
                [ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 ],
                [ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 ],
                [ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf ],
                [ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 ],
                [ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 ],
                [ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 ],
                [ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb ],
                [ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 ],
                [ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 ],
                [ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a ],
                [ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e ],
                [ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf ],
                [ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ]
            ]
    
            # 声明S盒的逆
            self.S_box_r = [
                [ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb ],
                [ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb ],
                [ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e ],
                [ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 ],
                [ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 ],
                [ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 ],
                [ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 ],
                [ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b ],
                [ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 ],
                [ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e ],
                [ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b ],
                [ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 ],
                [ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f ],
                [ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef ],
                [ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 ],
                [ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d ]
            ]
    
            # 声明RC常量
            self.RC = [ 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 ]
    
            # 声明列混淆矩阵常量
            self.BOX = [
                [ 0x02, 0x03, 0x01, 0x01 ],
                [ 0x01, 0x02, 0x03, 0x01 ],
                [ 0x01, 0x01, 0x02, 0x03 ],
                [ 0x03, 0x01, 0x01, 0x02 ]
            ]
    
            self.BOX_r = [
                [ 0x0e, 0x0b, 0x0d, 0x09 ],
                [ 0x09, 0x0e, 0x0b, 0x0d ],
                [ 0x0d, 0x09, 0x0e, 0x0b ],
                [ 0x0b, 0x0d, 0x09, 0x0e ]
            ]
    
            # 声明主要变量
            self.KEY, self.KEY_EXTEND = [ ], [ ]
    
        # 矩阵行列倒置
        def re_rc( self, box ):
            return [ [ row[ i ] for row in box ] for i in range(len(box[ 0 ])) ]
    
        # 矩阵内容16进制字符转10进制数字
        def str2dec( self, box ):
            for i in range(len(box)):
                for j in range(len(box[ i ])):
                    box[ i ][ j ] = int(box[ i ][ j ], 16)
            return box
    
        # 列混淆元计算
        def fun2( self, i ):
            i <<= 1
            if (i & 0x100 != 0):
                i = (i & 0xff) ^ 0x1b
            return i
    
        # 获取扩展密钥矩阵
        def get_extend( self, key, rc, count = 10 ):
            W = [ ]
            W_each_len = len(key)
            for col in self.re_rc(key):
                W.append("".join(hex(each)[ 2: ] for each in col).zfill(W_each_len * 2))
    
            for i in range(W_each_len, (count + 1) * W_each_len):
                if (i % W_each_len):
                    W.append(hex(int(W[ i - W_each_len ], 16) ^ int(W[ i - 1 ], 16))[ 2: ].zfill(W_each_len * 2))
                else:
                    W_tmp = "".join(hex(self.S_box[ int(each[ 0 ], 16) ][ int(each[ 1 ], 16) ])[ 2: ].zfill(2) for each in
                                    re.findall(r'\w{1,2}', W[ i - 1 ][ 2: ] + W[ i - 1 ][ :2 ]))
                    W.append(hex(
                        int(str(hex(int(W_tmp[ :2 ], 16) ^ rc[ i // W_each_len ]))[ 2: ].zfill(2) + W_tmp[ 2: ], 16) ^ int(
                            W[ i - W_each_len ],
                            16))[ 2: ].zfill(
                        W_each_len * 2))
    
            return [ [ W[ W_each_len * i + j ] for j in range(W_each_len) ] for i in range(len(W) // W_each_len) ]
    
        # 加密
        def aes_encode( self, content, key, rc, box, count = 10 ):
            key_re = self.re_rc(key)  # 密钥矩阵倒置
            content_re = self.re_rc(content)  # 明文矩阵倒置
            key_extend = self.get_extend(key, rc, count)  # 获取密钥扩展矩阵集
            aes_en = [ [ ] for i in range(len(key_re)) ]  # 预设加密结果矩阵
            aes_len = len(key_re)  # 计算矩阵边长
    
            # 首次轮密钥加
            for i in range(aes_len):
                for j in range(aes_len):
                    aes_en[ i ].append(hex(key_re[ i ][ j ] ^ content_re[ i ][ j ])[ 2: ].zfill(2))
    
            # 进行共10轮操作
            for this_round in range(count):
    
                # 字节替代
                for i in range(aes_len):
                    for j in range(aes_len):
                        aes_en[ i ][ j ] = hex(
                            self.S_box[ int(aes_en[ i ][ j ][ 0 ], 16) ][ int(aes_en[ i ][ j ][ 1 ], 16) ])[ 2: ].zfill(2)
    
                # 行位移
                aes_en = self.re_rc(aes_en)
                for i in range(1, aes_len):
                    for j in range(i):
                        aes_en[ i ].append(aes_en[ i ].pop(0))
                aes_en = self.re_rc(aes_en)
    
                # 若不为最后一次加密则进行列混淆
                if (this_round != 9):
                    for i in range(aes_len):
                        tmp_list = [ ]
                        for j in range(aes_len):
                            tmp_ = [ ]
                            for k in range(aes_len):
                                a = int(aes_en[ i ][ k ], 16)
                                b = bin(box[ j ][ k ])[ 2: ][ ::-1 ]
                                w = eval("^".join([ line for line in "^".join(
                                    [ "self.fun2(" * (bit - 1) + "a" * (bit > 0) + ")" * (bit - 1) for bit in
                                      [ pos * bool(int(b[ pos - 1 ])) for pos in range(1, len(b) + 1) ] ]).split('^') if
                                                    bool(line) ]))
                                tmp_.append(w)
                            tmp_list.append(hex(functools.reduce(lambda x, y: x ^ y, tmp_))[ 2: ].zfill(2))
                        aes_en[ i ] = tmp_list
    
                # 轮密钥加
                for i in range(aes_len):
                    tmp_list = re.findall(r'\w{1,2}', key_extend[ this_round + 1 ][ i ])
                    for j in range(aes_len):
                        aes_en[ i ][ j ] = hex(int(aes_en[ i ][ j ], 16) ^ int(tmp_list[ j ], 16))[ 2: ].zfill(2)
    
            return self.re_rc(aes_en)
    
        # 解密
        def aes_decode( self, passwd, key, rc, box, count = 10 ):
            passwd_re = self.re_rc(passwd)  # 密文矩阵倒置
            key_extend = self.get_extend(key, rc, count)  # 获取密钥扩展矩阵集
            aes_de = [ [ ] for i in range(len(key)) ]  # 预设解密结果矩阵
            aes_len = len(key)  # 计算矩阵边长
    
            # 首次轮密钥加
            for i in range(aes_len):
                for j in range(aes_len):
                    aes_de[ i ].append(
                        hex(int(key_extend[ count ][ i ][ j * 2:(j + 1) * 2 ], 16) ^ passwd_re[ i ][ j ])[ 2: ].zfill(
                            2))
    
            # 进行共10轮操作
            for this_round in range(count):
    
                # 进行逆向行位移
                aes_de = self.re_rc(aes_de)
                for i in range(1, aes_len):
                    for j in range(i):
                        aes_de[ i ].insert(0, aes_de[ i ].pop( ))
                aes_de = self.re_rc(aes_de)
    
                # 进行逆向字节替代
                for i in range(aes_len):
                    for j in range(aes_len):
                        aes_de[ i ][ j ] = hex(
                            self.S_box_r[ int(aes_de[ i ][ j ][ 0 ], 16) ][ int(aes_de[ i ][ j ][ 1 ], 16) ])[ 2: ].zfill(2)
    
                # 进行路密钥加
                for i in range(aes_len):
                    tmp_list = re.findall(r'\w{1,2}', key_extend[ count - this_round - 1 ][ i ])
                    for j in range(aes_len):
                        aes_de[ i ][ j ] = hex(int(aes_de[ i ][ j ], 16) ^ int(tmp_list[ j ], 16))[ 2: ].zfill(2)
    
                # 进行逆向列混淆
                if (this_round != 9):
                    for i in range(aes_len):
                        tmp_list = [ ]
                        for j in range(aes_len):
                            tmp_ = [ ]
                            for k in range(aes_len):
                                a = int(aes_de[ i ][ k ], 16)
                                b = bin(box[ j ][ k ])[ 2: ][ ::-1 ]
                                w = eval("^".join([ line for line in "^".join(
                                    [ "self.fun2(" * (bit - 1) + "a" * (bit > 0) + ")" * (bit - 1) for bit in
                                      [ pos * bool(int(b[ pos - 1 ])) for pos in range(1, len(b) + 1) ] ]).split('^') if
                                                    bool(line) ]))
                                tmp_.append(w)
                            tmp_list.append(hex(functools.reduce(lambda x, y: x ^ y, tmp_))[ 2: ].zfill(2))
                        aes_de[ i ] = tmp_list
    
            return self.re_rc(aes_de)
    
        def init( self, key, count = 10 ):
            self.KEY = key
            self.KEY_EXTEND = self.get_extend(key = key, rc = self.RC, count = count)
    
    
    def str2box( s, r = 4, l = 4, byte = 2 ):
        box = [ [ ] for i in range(r) ]
        for i in range(r):
            for j in range(l):
                box[ i ].append(int(s[ (i * r + j) * byte:((i * r + j) + 1) * byte ], 16))
        return box
    
    
    def box2str( box ):
        result = ""
        for row in range(len(box)):
            for each in box[ row ]:
                result += each
        return result
    
    # AES128加密
    def aes128_encode( content, aes, bit = 32, pad = '\n' ):
        s_hex_base64 = "".join([ "%2x" % ord(each) for each in b64.enb64(source = content, enbytes = False) ])
        s_hex_base64_plus = s_hex_base64 + "0" * (len(s_hex_base64) % bit) if len(
            s_hex_base64) > bit else s_hex_base64 + "0" * (bit - len(s_hex_base64))
        return pad.join(box2str(aes.aes_encode(
            content = aes.re_rc(str2box(s = s_hex_base64_plus[ index * bit:(index + 1) * bit ], r = 4, l = 4, byte = 2)),
            key = aes.KEY, rc = aes.RC, box = aes.BOX)) for index in range(len(s_hex_base64_plus) // bit))
    
    # AES128解密
    def aes128_decode( passwd, aes, bit = 32, pad = '\n' ):
        result = "".join(box2str(
            aes.re_rc(aes.aes_decode(passwd = str2box(s = line, r = 4, l = 4, byte = 2), key = aes.KEY, rc = aes.RC,
                                     box = aes.BOX_r))) for line in passwd.split(pad))
        return b64.deb64(
            "".join(chr(int(result[ i * 2:(i + 1) * 2 ], 16)) for i in range(len(result) // 2)).replace("\x00", ""),
            debytes = False)
    
    # 显示密钥矩阵
    def show_decbox( box ):
        for row in range(len(box)):
            print("[ " + " , ".join("0x" + hex(each)[ 2: ].zfill(2) for each in box[ row ]) + " ]")
        print("\n")
    
    # 显示密钥扩展矩阵
    def show_key_extend_box( box ):
        for row in range(len(box)):
            print("*" * 24 + "[ _ROUND_<%02d> ]" % row + "*" * 24)
            for i in range(len(box[ row ])):
                print("[ " + " , ".join(
                    "0x" + box[ row ][ j ][ i * 2:(i + 1) * 2 ].zfill(2) for j in range(len(box[ row ][ i ]) // 2)) + " ]")
        print("*" * 24 + "[ _END_ROUND_ ]" + "*" * 24 + "\n\n")
    
    
    def hex2str( s ):
        return "".join(chr(int(each, 16)) for each in re.findall(r'\w{1,2}', s)).encode('latin1')
    
    
    if __name__ == '__main__':
    
        # 密钥矩阵
        key = [
            [ 0x12, 0x34, 0x56, 0x78 ],
            [ 0x78, 0x65, 0x43, 0x21 ],
            [ 0x23, 0x33, 0x33, 0x33 ],
            [ 0x33, 0x33, 0x33, 0x32 ]
        ]
    
        aes = AES_128( )
        aes.init(key = key, count = 10)
        pad = "\n"
    
        print("*" * 52 + "[ AES128 ]" + "*" * 52)
        print("密钥矩阵 => ")
        show_decbox(aes.KEY)
        print("密钥扩展矩阵 => ")
        show_key_extend_box(aes.KEY_EXTEND)
        print("*" * 52 + "[ AES128 ]" + "*" * 52)
    
        while True:
            try:
                c = aes128_encode(content = input("请输入需要加密的信息:"), aes = aes, bit = 32, pad = pad)
                print("[ 密文  =》]")
                print(c)
                print("[ 密文流  =》]")
                print(hex2str(c.replace(pad, "")))
                s = aes128_decode(passwd = c, aes = aes, bit = 32, pad = pad)
                print("[ 明文  =》]")
                print(s)
            except KeyboardInterrupt:
                print("Bye!")
                exit(0)

  • RSA:
    '''
    @Description: RSA
    @Author: DQ
    @LastEditors  : DQ
    @Date: 2020-01-04 20:26:19
    @LastEditTime : 2020-03-15 03:03:20
    '''
    
    import random, b64, re, math
    
    
    class RSA_value(object):
        def __init__( self ):
            # 声明主要变量
            self.P, self.Q, self.N, self.Y, self.E, self.D = 0, 0, 0, 0, 0, 0
    
            # 声明小质数表
            self.small_primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
                                  59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127,
                                  131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191,
                                  193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
                                  269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347,
                                  349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421,
                                  431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499,
                                  503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593,
                                  599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
                                  661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751,
                                  757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
                                  853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937,
                                  941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013,
                                  1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
                                  1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
                                  1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
                                  1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,
                                  1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
                                  1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
                                  1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
                                  1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583,
                                  1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657,
                                  1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
                                  1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,
                                  1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889,
                                  1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987,
                                  1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
                                  2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129,
                                  2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213,
                                  2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287,
                                  2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
                                  2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423,
                                  2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531,
                                  2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617,
                                  2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
                                  2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741,
                                  2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819,
                                  2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903,
                                  2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
                                  3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079,
                                  3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181,
                                  3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257,
                                  3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
                                  3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413,
                                  3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511,
                                  3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571,
                                  3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
                                  3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727,
                                  3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821,
                                  3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907,
                                  3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
                                  4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057,
                                  4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139,
                                  4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231,
                                  4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
                                  4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409,
                                  4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493,
                                  4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583,
                                  4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
                                  4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751,
                                  4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831,
                                  4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937,
                                  4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003,
                                  5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087,
    
                                  5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179,
                                  5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279,
                                  5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387,
                                  5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443,
    
                                  5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521,
                                  5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639,
                                  5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693,
                                  5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791,
    
                                  5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857,
                                  5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939,
                                  5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053,
                                  6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133,
    
                                  6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221,
                                  6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301,
                                  6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367,
                                  6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473,
    
                                  6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571,
                                  6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673,
                                  6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761,
                                  6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833,
    
                                  6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917,
                                  6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997,
                                  7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103,
                                  7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207,
    
                                  7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297,
                                  7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411,
                                  7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499,
                                  7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561,
    
                                  7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643,
                                  7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723,
                                  7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829,
                                  7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919,
    
                                  7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017,
                                  8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111,
                                  8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219,
                                  8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291,
    
                                  8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387,
                                  8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501,
                                  8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597,
                                  8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677,
    
                                  8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741,
                                  8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831,
                                  8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929,
                                  8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011,
    
                                  9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109,
                                  9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199,
                                  9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283,
                                  9293, 9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377,
    
                                  9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439,
                                  9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533,
                                  9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631,
                                  9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733,
    
                                  9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811,
                                  9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887,
                                  9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973 ]
    
        # 递归求逆元
        def gcd( self, a, b ):  # 扩展欧几里算法优化版
            if (b == 0):
                return 1, 0
            else:
                x0, y0 = self.gcd(b, a % b)  # 递归计算a*x0 + b*y0=1(a与b互质)中的x0与y0值
                return y0, x0 - a // b * y0
    
        # 快速幂模算法
        def mod_quick( self, a, b, c ):  # a b c依次为基数 幂数 以及 模数
            array = bin(b)[ 2: ][ ::-1 ]  # 取幂数的二进制,并将其倒叙(从左到右→从小到大)
            n = len(array)  # 获取二进制数位数(也就是b的bits)
            result = 1  # 初始化结果
            if (array[ 0 ] == '1'):  # 这里以字符串的思想去判断,规避了int()的时间,若 b 的二进制首位为 1,将 a 填入列表
                result = a
    
            for _ in range(1, n):  # 循环遍历 b 的所有二进制位数
                next = (a * a) % c  # 循环幂模运算
                if (array[ _ ] == '1'):  # 若 b 的该二进制位值为 1,则进行计算
                    result = (result * next) % c
                a = next  # a 重定向幂模结果
            result %= c
            return result  # 返回结果
    
        # 判断大质数(拉宾米勒素性判断)
        def bool_p( self, N, X = 5 ):
            M = (N - 1) // 2  # N=(2**r)*M+1的反算
            r = 1
            while (not M % 2):  # 保证取到奇数M
                M //= 2
                r += 1
            for _ in range(X):
                A = random.randint(2, N - 1)  # 取随机数A
                get = self.mod_quick(A, M, N)  # 第四步测试 A**M%N==1则算通过1次测试
                if (get != 1):  # 此时get=(A**M)%N
                    i = 0  # 进行第三步测试 A**((2**i)*M)%N=N-1 i<r
                    while (get != N - 1):
                        if (i >= r - 1):  # 若i>=r则不通过
                            return False
                        else:
                            i += 1
                            get = (get * get) % N  # get=(A**(M*2**i))%N
            return True
    
        # 大质数生成(取P或Q的值)
        def get_p( self, size = 1024, seed = 0 ):
            random.seed = seed  # 设置随机种子保证取值广泛性
            while True:
                bool = False
                n = random.randint(2 ** (size - 2), 2 ** (size - 1)) * 2 + 1  # 保证奇数
                if (n % 6 != 5 and n % 6 != 1):  # 6左右判断法,大于4的素数必然是6的倍数-1或+1
                    continue
                for _ in self.small_primes:  # 模小质数表判断
                    if (not n % _):  # 若能模进则不为质数
                        bool = True
                        break
                if (not bool):
                    if (self.bool_p(n)):  # 进行拉宾米勒的素性判断
                        return n
    
        def q( self, size = 1024, seed = 0 ):
            return self.get_p(size = size, seed = seed)
    
        def p( self, size = 1024, seed = 0 ):
            return self.get_p(size = size, seed = seed)
    
        # 求E值与D值
        def e_d( self, N, size = 16, seed = 0 ):
            if (N != 0):
                random.seed = (seed)  # 设置随机种子
                while True:
                    e = self.get_p(size = size)  # 生成指定位的质数E,直至能够满足要求为止
                    d = self.gcd(e, N)[ 0 ]
                    if (d < 0):  # 若E与M(P-1)*(Q-1)组合不存在正确的D值则继续生成E
                        continue
                    else:
                        return e, d  # 若存在正确的D值则返回E值和D值
            else:
                return 0
    
        def init( self, size = 2048, seed = 0 ):
            self.P = self.p(size = size // 2, seed = seed)
            self.Q = self.q(size = size // 2, seed = seed)
            self.N = self.P * self.Q
            self.Y = (self.P - 1) * (self.Q - 1)
            self.E, self.D = self.e_d(N = self.Y)
    
    
    # 加密
    def rsa_encode( content, rsa, pad = '\n' ):
        s_hex_base64 = "".join([ "%2x" % ord(each) for each in b64.enb64(source = content, enbytes = False) ])
        rsa_hex_len = len(hex(rsa.N)[ 2: ]) - 1
        return pad.join(
            hex(rsa.mod_quick(int(s_hex_base64[ line * rsa_hex_len:(line + 1) * rsa_hex_len ], 16), rsa.E, rsa.N))[ 2: ] for
            line in range(math.ceil(len(s_hex_base64) / rsa_hex_len)))
    
    
    # 解密
    def rsa_decode( pass_v, rsa, pad = '\n' ):
        return b64.deb64("".join(chr(int(each, 16)) for each in re.findall(r'\w{1,2}', "".join(
            hex(rsa.mod_quick(int(line, 16), rsa.D, rsa.N))[ 2: ] for line in pass_v.split(pad)))), debytes = False)
    
    
    def hex2str( s ):
        return "".join(chr(int(each, 16)) for each in re.findall(r'\w{1,2}', s)).encode('latin1')
    
    def hex2str_crypt( s ,pad = '\n'):
        return[ "".join(chr(int(each, 16)) for each in re.findall(r'\w{1,2}', part)).encode('latin1') for part in [line for line in s.split(pad)] ]
    
    if __name__ == '__main__':
        rsa = RSA_value( )
        rsa.init(size = 16384)
        pad="\n"
        print("*" * 24 + "[ RSA ]" + "*" * 24)
        print("P => : ", hex2str(hex(rsa.P)[ 2: ]))
        print("Q => : ", hex2str(hex(rsa.Q)[ 2: ]))
        print("N => : ", hex2str(hex(rsa.N)[ 2: ]))
        print("E => : ", hex2str(hex(rsa.E)[ 2: ]))
        print("D => : ", hex2str(hex(rsa.D)[ 2: ]))
        print("*" * 24 + "[ RSA ]" + "*" * 24)
        while True:
            try:
                c = rsa_encode(content = input("请输入需要加密的信息:"), rsa = rsa,pad = pad)
                print("*" * 24 + "[ 密文  =》 ]" + "*" * 24)
                print("HEX => ","0x"+c)
                print("DEC => ",int(c,16))
                print("OCT => ",oct(int(c,16)))
                print("BIN => ",bin(int(c,16)))
                print("*" * 24 + "[ 密文流  =》]" + "*" * 24)
                print(hex2str_crypt(s = c, pad = pad))
                s = rsa_decode(pass_v = c, rsa = rsa, pad = pad)
                print("*" * 24 + "[ 明文  =》]" + "*" * 24)
                print(s)
            except KeyboardInterrupt:
                print("Bye!")
                exit(0)

  • SHA256:
    '''
    @Description: SHA256
    @Author: DQ
    @LastEditors  : DQ
    @Date: 2020-03-14 19:11:23
    @LastEditTime : 2020-03-15 05:10:59
    '''
    
    import re, functools
    
    
    class SHA_256(object):
        def __init__( self ):
    
            # 初始化哈希初值
            self.Hash_init = [
                0x6a09e667, 0xbb67ae85,
                0x3c6ef372, 0xa54ff53a,
                0x510e527f, 0x9b05688c,
                0x1f83d9ab, 0x5be0cd19
            ]
    
            # 初始化哈希常量
            self.Hash_const = [
                0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
                0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
                0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
                0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
                0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
                0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
                0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
                0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
            ]
    
        # 右旋转
        def rightrotate_( self, s, length ):
            return s[ -length: ] + s[ :-length ]
    
        # 右移位
        def rightshift_( self, s, length ):
            return "0" * length + s[ :-length ]
    
        # hash加
        def hash_add( self, x, y ):
            return (x + y) & 0xffffffff
    
        # 扩充内容
        def prepare_( self, data ):
            try:
                data = data.encode( )
            except AttributeError:
                data = data
            data_bin_steam = "".join(bin(each)[ 2: ].zfill(8) for each in data)
            data_bin_len = len(data_bin_steam)
            data_append = ((448 - (data_bin_len % 512)) if (data_bin_len % 512) < 448 else (448 + 512 - (data_bin_len % 512))) - 1
    
            return data_bin_steam + "1" + "0" * data_append + bin(
                data_bin_len)[ 2: ].zfill(64)
    
        # hash256
        def main_( self, data ):
            data_blocks = [ data[ index*512:(index + 1) * 512 ] for index in range(len(data) // 512) ]
            data_hash_main = self.Hash_init.copy( )
    
    
            # 对每个块进行摘要
            for block in data_blocks:
    
                # 求W[0~15]
                W = re.findall('\d{32}', block[ :32 * 16 ])
    
                # 求W[16~63]
                for i in range(16, 64):
                    o0 = int(self.rightrotate_(W[ i - 15 ], 7), 2) ^ \
                         int(self.rightrotate_(W[ i - 15 ], 18), 2) ^ \
                         int(self.rightshift_(W[ i - 15 ], 3), 2)
    
                    o1 = int(self.rightrotate_(W[ i - 2 ], 17), 2) ^ \
                         int(self.rightrotate_(W[ i - 2 ], 19), 2) ^ \
                         int(self.rightshift_(W[ i - 2 ], 10), 2)
                    W.append(bin(functools.reduce(self.hash_add, [ int(W[ i - 16 ], 2), o0, int(W[ i - 7 ], 2), o1 ]))[2: ].zfill(32))
    
                data_hash = data_hash_main.copy( )
    
                # 进行64轮摘要
                for i in range(64):
                    s0 = int(self.rightrotate_(bin(data_hash[ 0 ])[ 2: ].zfill(32), 2), 2) ^ \
                         int(self.rightrotate_(bin(data_hash[ 0 ])[ 2: ].zfill(32), 13), 2) ^ \
                         int(self.rightrotate_(bin(data_hash[ 0 ])[ 2: ].zfill(32), 22), 2)
    
                    maj = (data_hash[ 0 ] & data_hash[ 1 ]) ^ \
                          (data_hash[ 0 ] & data_hash[ 2 ]) ^ \
                          (data_hash[ 1 ] & data_hash[ 2 ])
    
                    s1 = int(self.rightrotate_(bin(data_hash[ 4 ])[ 2: ].zfill(32), 6), 2) ^ \
                         int(self.rightrotate_(bin(data_hash[ 4 ])[ 2: ].zfill(32), 11), 2) ^ \
                         int(self.rightrotate_(bin(data_hash[ 4 ])[ 2: ].zfill(32), 25), 2)
    
                    ch = (data_hash[ 4 ] & data_hash[ 5 ]) ^ ((~data_hash[ 4 ]) & data_hash[ 6 ])
    
                    t1 = functools.reduce(self.hash_add,[ data_hash[ 7 ], s1, ch, self.Hash_const[ i ] + int(W[ i ], 2)])
                    t2 = functools.reduce(self.hash_add, [ s0, maj ])
    
                    data_hash=[ self.hash_add(data_hash[i - 1] ,t1*(not i%4 )) for i in range(1,8)]
                    data_hash.insert(0, self.hash_add(t1,t2))
    
                    #print("<%d>[ "%i+" , ".join(hex(each) for each in data_hash)+"]")
    
                data_hash_main = [ self.hash_add(data_hash[ i ],data_hash_main[ i ]) for i in range(8) ]
            return "".join(hex(each)[ 2: ].zfill(2) for each in data_hash_main)
    
    
    def show_decbox( box , length):
        for row in range(len(box) // length):
            print("[ " + " , ".join("0x" + hex(each)[ 2: ].zfill(8) for each in [box[row*length + i] for i in range(length)]) + " ]")
        print("\n")
    
    
    if __name__ == '__main__':
        sha256=SHA_256()
    
        print("*" * 52 + "[ SHA256 ]" + "*" * 52)
        print("哈希初值 => ")
        show_decbox(sha256.Hash_init,2)
        print("哈希常量 => ")
        show_decbox(sha256.Hash_const, 8)
        print("*" * 52 + "[ SHA256 ]" + "*" * 52)
    
        while True:
            try:
                c = sha256.main_(data = sha256.prepare_(data = input("请输入需要进行SHA256的值:")))
                print("[ SHA256  =》]")
                print(c)
            except KeyboardInterrupt:
                print("Bye!")
                exit(0)
    

生成随机字节流的处理代码实现:

  • 生成[密钥KEY1]以及[密钥KEY2]:
    import time,psutil,c64,sha256
    
    def get_handware_data():
        # 获取当前内存数据
        memory_data = psutil.virtual_memory()
        # 求当前内存使用率(结果精确至小数点后48位)
        memory_use = str("%.48f"%(memory_data.used / memory_data.total))
        # 获取当前CPU数据
        cpu_info = psutil.cpu_times()
        cpu_status = "|".join(str(each) for each in (cpu_info.user,cpu_info.nice,cpu_info.system))
        return cpu_status + "|" + memory_use
    
    def get_key_1(s:str):
        # 生成[密钥KEY1]
        SHA256 = sha256.SHA_256()
        return SHA256.main_(SHA256.prepare_(c64.encrypt(s)))[:32]
    
    def get_key_2(s:str):
        # 通过[密钥KEY1]来生成[密钥KEY2]
        SHA256 = sha256.SHA_256()
        return SHA256.main_(SHA256.prepare_(c64.encrypt(str(time.time()).replace('.','')+s)))[:32]
    
    def get_key():
        # 获取生成的两个密钥
        key1 = get_key_1(get_handware_data())
        key2 = get_key_2(key1)
        return key1,key2
    
    if __name__ == '__main__':
        key1,key2 = get_key()
        print(key1)
        print(key2)
    

  • 生成随机字节流:
    import rsa,sha256,aes128,sys,time
    
    def get_rsa_data():
    
        # 获取RSA数据
    
        RSA = rsa.RSA_value()
        RSA.init(2048)
        return RSA
    
    def get_aes128_box(box:list):
    
        # AES128密钥矩阵转换单行数据
    
        return [[box[i*4+j] for j in range(4)] for i in range(4)]
    
    def get_aes128_box_r(box:list):
    
        # 单行数据转换AES128密钥矩阵
    
        temp_list=[]
        for i in range(4):
            for j in range(4):
                temp_list.append(box[i][j])
        return temp_list
    
    def get_rand_1(key2:str,p:str,count:int = 5):
    
        # [第二步] 的操作
    
        AES = aes128.AES_128()
        SHA256 = sha256.SHA_256()
        aes_key = get_aes128_box([int(key2[i*2:(i+1)*2],16) for i in range(len(key2)//2)])
    
        result = SHA256.main_(SHA256.prepare_(p))
    
        for i in range(count):
            AES.init(aes_key,10)
            AES_c = aes128.aes128_encode(result,AES,32,'')
            if(count != 4):
                if(not i%2):
                    aes_get = AES_c[-32:]
                else:
                    aes_get = AES_c[32:]
                aes_key = get_aes128_box([a ^ b for a,b in zip(get_aes128_box_r(aes_key),[int(aes_get[j*2:(j+1)*2],16) for j in range(len(aes_get)//2)])])
                result = SHA256.main_(SHA256.prepare_(AES_c))
            else:
                result = AES_c
    
        return result
            
    def get_rand_2(request_time:str,mainkey:str,q:str,count:int = 5):
    
        # [第三步] 的操作
    
        AES = aes128.AES_128()
        SHA256 = sha256.SHA_256()
        aes_key = get_aes128_box([int(mainkey[i*2:(i+1)*2],16) for i in range(len(mainkey)//2)])
        aes_q_key =[int(q[i*2:(i+1)*2],16) for i in range(len(q[:32])//2)]
        timestamp = str(time.time()).replace('.','')
        result = request_time + timestamp
        
        for i in range(count):
            AES.init(aes_key,10)
            AES_c = aes128.aes128_encode(result,AES,32,'')
            if(i != 4):
                aes_key = get_aes128_box([a ^ b for a,b in zip(get_aes128_box_r(aes_key),aes_q_key)])
                result = SHA256.main_(SHA256.prepare_(AES_c))
            else:
                result = AES_c
            
        return result
    
    def get_rand_3(rand1:str,rand2:str,RSA):
    
        # [第四步] 的操作
    
        rand1_xor_rand2 = "".join(chr(ord(a) ^ ord(b)) for a,b in zip(rand1,rand2))
        RSA_c = rsa.rsa_encode(rand1_xor_rand2,RSA,'')
        return RSA_c
    
    def get_result(s:str,n:str):
    
        # [第五步] 的操作
    
        SHA256 = sha256.SHA_256()
        s_or_n = "".join(chr(ord(a) | ord(b)) for a,b in zip(s,n))
        left = SHA256.main_(SHA256.prepare_(s[:len(s)//2]))
        right = SHA256.main_(SHA256.prepare_(s[-len(s)//2:]))
        result = left + SHA256.main_(SHA256.prepare_(s_or_n)) + right
        
        return result
    
    def get_random(key2:str,mainkey:str,request_time:str):
    
        # [第一步]
        RSA = get_rsa_data()
    
        # [第二步]
        rand1 = get_rand_1(key2,hex(RSA.P)[2:],5)
    
        # [第三步]
        rand2 = get_rand_2(request_time,mainkey,hex(RSA.Q)[2:],5)
    
        # [第四步]
        rand3 = get_rand_3(rand1,rand2,RSA)
        
        # [第五步]
        result = get_result(rand3,hex(RSA.N)[2:])
    
        return result
    
    if __name__ == '__main__':
        if(len(sys.argv) == 4):
            print(get_random(sys.argv[1],sys.argv[2],sys.argv[3]))
        else:
            exit(0)
    

后端代码的实现:

  • main.php:
    <?php
    	session_start();
    
    	class Rand_config{
    		
    		# 操作选项
    		private $setting = ['get_rand_key','refresh_rand_key','get_rand_result','refresh_rand_result'];
    		
    		# 调用Python的结果
    		private $cmd_result;
    
    		# 存储在服务器的 [不变密钥KEY]
    		private $private_key = '43fada45363a416167d4b3dadc2f7b49';
    		
    		private $result = '';
    		private $status = '';
    		private $error = '';
    		
    		private function exec_cmd($cmd){
    			# 调用Python
    			exec($cmd,$this->cmd_result);
    			$this->result = count($this->cmd_result) > 0 ? implode('|',$this->cmd_result) : $this->result = '出错了!';
    		}
    		
    		
    		public function __construct($type = null){
    			try{
    				
    				if(!is_null($type)){
    					
    					if(in_array($type,$this->setting,true)){
    						
    						# 获取当前操作的索引值
    						$index = array_search($type,$this->setting);
    						
    						switch ($index){
    							
    							# 获取[密钥KEY1]以及[密钥KEY2]的调用Python操作
    							case 0: 
    								# 设置Python处理时间
    								$_SESSION['endtime_key'] = time() + .5;
    								# 调用Python进行处理
    								$this->exec_cmd('python3 /app/a.py');
    								if($this->result != '出错了!'){
    									
    									# 若处理成功则获得[密钥KEY1]和[密钥KEY2]
    									$_SESSION['key'] = $this->result;
    									$this->status = "exec";
    								}else{
    									$this->status = "failed";
    								}
    							break;
    							
    							# 获取[密钥KEY1]以及[密钥KEY2]的刷新操作
    							case 1:
    								if(isset($_SESSION['endtime_key']) and $_SESSION['endtime_key'] <= time()){
    									
    									# 若处理完成且获取成功,则返回OK
    									$this->status = 'OK';
    								}
    							break;
    							
    							# 获取随机字符的一系列操作
    							case 2:
    								if(isset($_POST['request_time']) and isset($_SESSION['key']) and isset($_POST['fonts']) and isset($_POST['url_decode']) and isset($_POST['len'])){
    									
    									# 设置Python处理时间
    									$_SESSION['endtime_result'] = time() + 2;
    									# 获取当前的[密钥KEY1]和[密钥KEY2]
    									$keys = explode('|',$_SESSION['key']);
    									
    									# 使用者是否要求对其他字符预先进行URL解码
    									$fonts = $_POST['url_decode'] === 'true' ? urldecode($_POST['fonts']) : $_POST['fonts'];
    									
    									# 将使用者选定的随机字符列表添加入数组,并去重
    									$result_array = preg_split('//', $fonts, -1, PREG_SPLIT_NO_EMPTY);
    									array_unique($result_array);
    									$len = count($result_array);
    									
    									# 获取使用者要求的随机字符长度(字节数)
    									$rand_len = ($_POST['len'] > 90 or $_POST['len'] <= 0) ? 45 : $_POST['len'];
    									
    									if(count($keys) === 2){
    										
    										# 若一切无误则调用Python生成随机字节流
    										$this->exec_cmd("python3 /app/b.py ".join(' ',[$keys[0],$keys[1],intval($_POST['request_time']])));
    										if($this->result != '出错了!'){
    											
    											# 获取生成的随机字节流并逐个字节添加入数组
    											$_SESSION['rand'] = $this->result;
    											$contents = '';	
    											preg_match_all('/[\S\s]{2}/i',$_SESSION['rand'],$bytes,2);
    											
    											# 使用生成的随机字节流生成随机字符
    											for($i = 0;$i < $rand_len;$i++){ $contents .= $result_array[hexdec($bytes[$i][0]) % $len];}
    											$_SESSION['rand_str'] = $contents;
    											$this->status = 'exec';
    											
    										}else{
    											
    											$this->status = 'failed';
    										}
    									}else{
    										
    										$this->status = 'failed';
    									}
    								}else{
    									
    									$this->status = 'failed';
    								}
    							break;
    							
    							# 获取随机字符的刷新操作
    							case 3:
    								if(isset($_SESSION['endtime_result']) and $_SESSION['endtime_result'] <= time()){
    									
    									# 若处理完成且获取成功,则返回OK
    									$this->status = 'OK';
    								}
    							break;
    						}
    					}
    				}
    				
    			}catch(Exception $e){
    				
    				$this->error = $e->getMessage()."\x0a".'出错了!';
    			}
    		}
    		
    		public function __toString(){
    			
    			return $this->error === '' ? (string)$this->status : (string)$this->error;
    		}
    	}
    	
    	# 将操作得到的结果以JSON方式返回,方便前端的jQuery处理
    	function json_result($type,$status,$contents = ''){
    		header("Content-Type: text/json");
    		echo json_encode(array(
    		'type'=>$type,
    		'status'=>$status,
    		'result'=>base64_encode($contents)
    		));
    	}
    	
    	
    	# 请求传入的入口
    	# 对传入的请求判断并进行对应的操作
    	if(isset($_POST['action'])){
    		
    		$status = (string) new Rand_config($_POST['action']);
    		
    		if($status === 'OK'){
    			if($_POST['action'] === 'refresh_rand_key'){
    				
    				json_result($_POST['action'],$status,$_SESSION['key']);
    				
    			}else if($_POST['action'] === 'refresh_rand_result'){
    
    				json_result($_POST['action'],$status,$_SESSION['rand_str']);
    				
    			}
    		}else{
    			json_result($_POST['action'],$status);
    		}
    		
    		
    	}
    
    
    ?>
    

效果演示:

  • 主界面:

    image-20200520144239928.png


  • 随意生成一个长度为 60 的随机字符:

    image-20200520144606393.png


  • 使用[将其他字符URL解码]功能,生成包含扩展ascii的内容:

    image-20200520144417007.png


  • 由于html可能无法正确解析一些扩展ascii码的内容,实际上在index.php的返回的JSON数据流是使用了BASE64将随机字符预先编码的,因而可以直接将JSON中的BASE64解码即可得到一些html无法正常显示的随机字符:

    image-20200520145038721.png

  • 以及:

    image-20200520145309953.png


    *最后关于中文的问题,由于这个随机原理是以单字节为基本单位操作,而中文是由多字节组成,所以无法支持随机中文字符。