美文网首页NJUPT 计软院 复习资料
NJUPT【信息安全综合实验】

NJUPT【信息安全综合实验】

作者: Du1in9 | 来源:发表于2022-05-25 12:57 被阅读0次
    https://wwb.lanzouh.com/i8uxY05qu1mf

    题目2:RSA-OAEP的实现

    具体要求
    RSA算法是应用最为广泛的公钥加密算法之一,但由于基本算法具有的同态性,在实际使用过程中,通常需要对基本的RSA算法进行改进,而RSA-OAEP算法即为实际使用算法之一。本课题致力于对RSA-OAEP算法的模拟实现,使学生深入了解基本RSA算法如何应用到实际的机密性问题解决中,提升编程能力。
    题目的具体要求
    1.查阅相关资料,深入了解RSA-OAEP算法的实现思想和原理;
    2.选择一种编程语言和开发工具,模拟实现RSA-OAEP算法的加解密,并能够实现对文字信息的加解密;
    3.程序具有图形化用户界面,输出美观;
    4.可根据自己能力,在完成以上基本要求后,对程序功能进行适当扩充;
    5.撰写报告,对所采用的算法、程序结构和主要函数过程以及关键变量进行详细的说明;对程序的调试过程所遇到的问题进行回顾和分析,对测试和运行结果进行分析;总结软件设计和实习的经验和体会,进一步改进的设想;
    6.提供关键程序的清单、源程序及可执行文件和相关的软件说明。
    附(RSA-OAEP算法)


    加密1) Alice 填充信息来制成一个m比特的信息,我们称之为M。
    加密2) Alice 选择一个k比特的随机数r(注意r只能使用一次然后就要销毁)。Alice运用MD4函数G,用r生成一个m比特的整数,创建部分明文 然后创建部分明文 这里函数H也选用MD4,将m比特的输入生成k比特的输出。
    加密3) Alice 创建密文 并且把C发送给Bob。
    解密1) Bob 创建
    解密2) Bob 首先运用 重新创建r的值。然后运用 重新创建填充信息的值。
    解密3) 从M当中取消填充后,Bob得到了原信息。
    # OAEP_easyRealize.py
    
    from Crypto.PublicKey import RSA
    from Crypto.Cipher import PKCS1_OAEP
    import base64
    
    rsa_key_pair = RSA.generate(1024)
    pubkey = rsa_key_pair.publickey().export_key()
    privkey = rsa_key_pair.export_key()
    print(pubkey.decode())
    print(privkey.decode())
     
    # 公钥加密
    text = "hello world"
    rsa_pubkey = RSA.import_key(pubkey)
    cipher_pub = PKCS1_OAEP.new(rsa_pubkey)
    ciphervalue_enc = base64.b64encode(cipher_pub.encrypt(text.encode("utf-8")))
    print("加密内容:\n{}".format(ciphervalue_enc.decode()))
    
    #私钥解密
    rsa_privkey = RSA.import_key(privkey)
    cipher_priv = PKCS1_OAEP.new(rsa_privkey)
    ciphervalue_dec = cipher_priv.decrypt(base64.b64decode(ciphervalue_enc))
    print("解密内容:\n{}".format(ciphervalue_dec.decode()))
    
    -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwwyKOjYBImX1onWvJNBMNmp+0
    f0sp71Fhzj2EPQQv5puPP7dNpSdqQ1GgMIKRgc5tClyaw+gtuY1MGaL++oQg543t
    pnPfFVXzmi1j0rRl1KSljfI8eiQ5XLu/t+FCn9kVltZTWaXBxmloWwPbphhkgVur
    yxCxhCKAf2n4KSJM/wIDAQAB
    -----END PUBLIC KEY-----
    
    -----BEGIN RSA PRIVATE KEY-----
    MIICXQIBAAKBgQCwwyKOjYBImX1onWvJNBMNmp+0f0sp71Fhzj2EPQQv5puPP7dN
    pSdqQ1GgMIKRgc5tClyaw+gtuY1MGaL++oQg543tpnPfFVXzmi1j0rRl1KSljfI8
    eiQ5XLu/t+FCn9kVltZTWaXBxmloWwPbphhkgVuryxCxhCKAf2n4KSJM/wIDAQAB
    AoGAO7/qSXeJWoEPxDIaQivpGNsgivnQZX9w6fe2EaIybSKtiLGH+6YM+b2BtP1Q
    1XCkX3V2MhZwwCwNmCC+WSRDTvBE2/POkNAifEoruk1a9+V5Mc4FXb48iH4+chF9
    Spzg2Oj/IJ4NAVNW8sPIo4JCrfRtJcor9kkXvV3RSJgs+hECQQDSqne5SRtLG3r7
    DozGlqjj950RixP5hYYyA7Gs4zHTW7gcwsUs0g7UF9nHFC0GGcuw1YqMxl4vqelN
    m4vymUVZAkEA1szshJdBw+1LmnaUSZFdTC/SGdcC7UoRHqTGnbb7xsaWHVbN3qS4
    M1dMj8KHizP+pQ+HNbIO89bqufaQQDliFwJBAMSXzoh7n9vUdkzpxBfjKxMq1Uo0
    1twpbhUoe1uS3cGXO1ajsGvmT25AH7x3qJij5AFPFi/PQsAKOS1ydgRcYmkCQDpB
    TYwQMafffXeg3Uquf+0fsw2LAKI2SjpTWgKAE/yu8xt15VOSvNo/vOXoTjZ0nYVK
    ltL7PY7oJLTWp/yjE3UCQQCOZ7+yo4rCE8r43JSlayonVVMA4hrC8F3KfGPm0F1e
    C9uXZucT9xYGOebvy68vrf/Sdd4aqpQ5nsDFPYrYkmkm
    -----END RSA PRIVATE KEY-----
    
    加密内容:
    U4hxfy8iHhw/L2ZWF2y1Mq9fO3xuxHHqDe7rt9lG38TeB8pwNgRQcQOBa90aiEQfZTu0JnCHm69riV2yAXk9Q/Khk0jp5Xmb/QcLa+ndTO7ncOsESwDA9BLYgPV0qEF2MCeJx3f2374dq3oSBC8cv+SIUb98WLQ0nPpH+tMW2Ag=
    
    解密内容:
    hello world
    
    # MD4_Realize.py
    
    maxInt = 0x100000000
    S = [3, 7, 11, 19, 3, 7, 11, 19,
         3, 7, 11, 19, 3, 7, 11, 19,
         3, 5, 9, 13, 3, 5, 9, 13,
         3, 5, 9, 13, 3, 5, 9, 13,
         3, 9, 11, 15, 3, 9, 11, 15,
         3, 9, 11, 15, 3, 9, 11, 15, ]
    
    K = [0x00000000, 0x00000000, 0x00000000, 0x00000000,
         0x00000000, 0x00000000, 0x00000000, 0x00000000,
         0x00000000, 0x00000000, 0x00000000, 0x00000000,
         0x00000000, 0x00000000, 0x00000000, 0x00000000,
         0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999,
         0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999,
         0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999,
         0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999,
         0X6ED9EBA1, 0X6ED9EBA1, 0X6ED9EBA1, 0X6ED9EBA1,
         0X6ED9EBA1, 0X6ED9EBA1, 0X6ED9EBA1, 0X6ED9EBA1,
         0X6ED9EBA1, 0X6ED9EBA1, 0X6ED9EBA1, 0X6ED9EBA1,
         0X6ED9EBA1, 0X6ED9EBA1, 0X6ED9EBA1, 0X6ED9EBA1, ]
    
    
    def fill(sequence):
        '将字节序列按小端序填充成512位【16整数*4字节】的倍数'
        count = len(sequence)
        multi_16s = ((count + 8) // 64 + 1) * 16  # 共需要整数的个数,每个整数存储4个字节的数据
        sequence += [0] * (multi_16s * 4 - count)  # 用 0 填充
        sequence[count] |= 128  # 用一个 1 补在后面
        multi_4bytes = []
        for i in range(len(sequence) // 4):
            sequence[i * 4 + 3], sequence[i * 4 + 2], sequence[i * 4 + 1], sequence[i * 4] = tuple(
                sequence[i * 4:(i + 1) * 4])  # 大端序存储
            multi_4bytes.append(
                int("".join(["{:08b}".format(ii) for ii in sequence[i * 4:(i + 1) * 4]]), 2))  # 每四个Ascii合并成一个4字节整数
        multi_4bytes[-2], multi_4bytes[-1] = int("{:064b}".format(count * 8)[32:], 2), int("{:064b}".format(count * 8)[:32],
                                                                                           2)
        return multi_4bytes
    
    
    def fill(sequence):
        '将字节序列按小端序填充成512位【16整数*4字节】的倍数'
        count = len(sequence)
        multi_16s = ((count + 8) // 64 + 1) * 16  # 共需要整数的个数,每个整数存储4个字节的数据
        sequence += [0] * (multi_16s * 4 - count)  # 用 0 填充
        sequence[count] |= 128  # 用一个 1 补在后面
        multi_4bytes = []
        for i in range(len(sequence) // 4):
            sequence[i * 4 + 3], sequence[i * 4 + 2], sequence[i * 4 + 1], sequence[i * 4] = tuple(
                sequence[i * 4:(i + 1) * 4])  # 大端序存储
            multi_4bytes.append(
                int("".join(["{:08b}".format(ii) for ii in sequence[i * 4:(i + 1) * 4]]), 2))  # 每四个Ascii合并成一个4字节整数
        multi_4bytes[-2], multi_4bytes[-1] = int("{:064b}".format(count * 8)[32:], 2), int("{:064b}".format(count * 8)[:32],
                                                                                           2)
        return multi_4bytes
    
    
    def shift(x, n):
        '循环左移'
        return ((x << n) | (x >> (32 - n)))
    
    
    def F(X, Y, Z): return (X & Y) | ((~X) & Z)
    
    
    def G(X, Y, Z): return (X & Y) | (X & Z) | (Y & Z)
    
    
    def H(X, Y, Z): return X ^ Y ^ Z
    
    
    def Go(a, b, c, d, fun, m, s, K):
        thesum = (a + fun(b, c, d) + int(m) + K) % maxInt
        return shift(thesum, s) % maxInt
    
    
    def int32ToHex(a):
        '32位整型集合转16进制'
        md4 = ''
        for i in a:
            x = "{:08x}".format(i)  # 整型【32位2】->8位16
            md4 += x[6:] + x[4:6] + x[2:4] + x[:2]  # 每两位切割, 切割4刀->逆序【大端变小端】
        return md4
    
    
    def MD4(text):
        # 程序中:大端字节序
        A = 0X67452301
        B = 0XEFCDAB89
        C = 0X98BADCFE
        D = 0X10325476
        sequence = list(bytes(text, 'utf-8'))  # 将unicode转换为字节序列
        text_int4 = fill(sequence)  # 将字节序列按小端序填充成4字节整数
        for i in range(len(text_int4) // 16):  # 主循环
            a, b, c, d = A, B, C, D
            M = [text_int4[i * 16 + ii] for ii in range(16)]  # 取出16个整数
            for ii in range(48):
                if ii < 16:
                    A, B, C, D = D, Go(A, B, C, D, F, M[ii], S[ii], K[ii]), B, C
                elif ii == 16:
                    A = Go(A, B, C, D, G, M[0], S[ii], K[ii])
                elif ii == 17:
                    D = Go(D, A, B, C, G, M[4], S[ii], K[ii])
                elif ii == 18:
                    C = Go(C, D, A, B, G, M[8], S[ii], K[ii])
                elif ii == 19:
                    B = Go(B, C, D, A, G, M[12], S[ii], K[ii])
                elif ii == 20:
                    A = Go(A, B, C, D, G, M[1], S[ii], K[ii])
                elif ii == 21:
                    D = Go(D, A, B, C, G, M[5], S[ii], K[ii])
                elif ii == 22:
                    C = Go(C, D, A, B, G, M[9], S[ii], K[ii])
                elif ii == 23:
                    B = Go(B, C, D, A, G, M[13], S[ii], K[ii])
                elif ii == 24:
                    A = Go(A, B, C, D, G, M[2], S[ii], K[ii])
                elif ii == 25:
                    D = Go(D, A, B, C, G, M[6], S[ii], K[ii])
                elif ii == 26:
                    C = Go(C, D, A, B, G, M[10], S[ii], K[ii])
                elif ii == 27:
                    B = Go(B, C, D, A, G, M[14], S[ii], K[ii])
                elif ii == 28:
                    A = Go(A, B, C, D, G, M[3], S[ii], K[ii])
                elif ii == 29:
                    D = Go(D, A, B, C, G, M[7], S[ii], K[ii])
                elif ii == 30:
                    C = Go(C, D, A, B, G, M[11], S[ii], K[ii])
                elif ii == 31:
                    B = Go(B, C, D, A, G, M[15], S[ii], K[ii])
                elif ii == 32:
                    A = Go(A, B, C, D, H, M[0], S[ii], K[ii])
                elif ii == 33:
                    D = Go(D, A, B, C, H, M[8], S[ii], K[ii])
                elif ii == 34:
                    C = Go(C, D, A, B, H, M[4], S[ii], K[ii])
                elif ii == 35:
                    B = Go(B, C, D, A, H, M[12], S[ii], K[ii])
                elif ii == 36:
                    A = Go(A, B, C, D, H, M[2], S[ii], K[ii])
                elif ii == 37:
                    D = Go(D, A, B, C, H, M[10], S[ii], K[ii])
                elif ii == 38:
                    C = Go(C, D, A, B, H, M[6], S[ii], K[ii])
                elif ii == 39:
                    B = Go(B, C, D, A, H, M[14], S[ii], K[ii])
                elif ii == 40:
                    A = Go(A, B, C, D, H, M[1], S[ii], K[ii])
                elif ii == 41:
                    D = Go(D, A, B, C, H, M[9], S[ii], K[ii])
                elif ii == 42:
                    C = Go(C, D, A, B, H, M[5], S[ii], K[ii])
                elif ii == 43:
                    B = Go(B, C, D, A, H, M[13], S[ii], K[ii])
                elif ii == 44:
                    A = Go(A, B, C, D, H, M[3], S[ii], K[ii])
                elif ii == 45:
                    D = Go(D, A, B, C, H, M[11], S[ii], K[ii])
                elif ii == 46:
                    C = Go(C, D, A, B, H, M[7], S[ii], K[ii])
                else:
                    B = Go(B, C, D, A, H, M[15], S[ii], K[ii])
            A, B, C, D = (A + a) % maxInt, (B + b) % maxInt, (C + c) % maxInt, (D + d) % maxInt  # 此处还是大端字节
        md4 = int32ToHex([A, B, C, D])
        return md4
    
    # OAEP_Realize.py
    
    import random
    import binascii
    import easygui
    import MD4_Realize
    
    
    def gcd(a, b):  # 求最大公因数
        while a != 0:
            a, b = b % a, a
        return b
    
    
    def findModReverse(e, n):  # 已知e和n,求d,满足关系式:ed = 1 mod φ(n)
        if gcd(e, n) != 1:
            return None
        u1, u2, u3 = 1, 0, e
        v1, v2, v3 = 0, 1, n
        while v3 != 0:
            q = u3 // v3  # 整除
            u1, u2, u3, v1, v2, v3 = v1, v2, v3, (u1 - q * v1), (u2 - q * v2), (u3 - q * v3)
        return u1 % n
    
    
    if __name__ == "__main__":
        p = 168995677594036943498896698249502579045415356147450286903574977915675215654000852466242837180568368549600306461919095156035850147291191251838345423003548737288250427664794031697769270068290742307294644975782315875706815176748955712747679225674789516554407102487179525812178429394677953163553303283966837950227
        q = 73250114511939221297189302708624091354575379476811068897570041621344734046574044427415715091676742616301137831925511472461697934230365993146217113253076136386575575868816429181422361239620593954716878229091392314316476106540409390466346705287246245765228049884691190461308813988563356306637349832642629018559
    
        plaintext = easygui.enterbox("请输入加密字符串:")
        Pri_Key = 17340019
        print("\n输入值M: " + plaintext)
    
        r = ""
        for i in range(1024):
            r += str(random.randint(0, 1))
        print("\n1024位随机数r: " + r)
    
        pad_paintext = binascii.hexlify(plaintext.encode('utf8'))
        print("\n输入值M的ascii值: " + str(pad_paintext))
    
        # RSA-OAEP
        mark_r = str(hex(int(r, 2)))
        P1 = MD4_Realize.MD4(mark_r)
        print("\nr的md4值: " + P1)
        P1 = str(hex(int(P1, 16) ^ int(pad_paintext, 16)))
    
        mark_r = P1
        P2 = MD4_Realize.MD4(mark_r)
        print("\nP1的md4值: " + P2)
        P2 = str(hex(int(P2, 16) ^ int(r, 2)))
        P1 = P1 + P2[2:]
        print("\n明文P=(P1+P2): " + P1)
        xx = int(P1, 16)
    
        mul_pq = p * q
        print("\n大素数p = " + str(p) + "\nq = " + str(q))
        print("\nn = p * q: " + str(mul_pq))
        fn = (p - 1) * (q - 1)
        print("\nφ(n) = (p - 1) * (q - 1): " + str(fn))
        Pub_Key = findModReverse(Pri_Key, fn)
        print("\n私钥e: " + str(Pri_Key) + "\n公钥d = reverseMod(e, φ(n)): " + str(Pub_Key))
        Ey = int(pow(xx, Pub_Key, mul_pq))
        print("\n密文C = p^e (mod n): " + str(Ey))
    
        easygui.msgbox("1024位随机数r:\n" + r)
        easygui.msgbox("\n\nOAEP加密结果:\n" + str(P1[2:])
                       + "\n\nOAEP十进制结果:\n" + str(xx)
                       + "\n\nRSA加密后密文:\n" + str(hex(Ey)))
    
        # decode
        Ex = int(pow(Ey, Pri_Key, mul_pq))
        print("\n解密后明文deP = C^d (mod n): " + str(Ex))
        deS = bin(Ex)
        deP2 = hex(int(deS[len(deS) - 1024:], 2))
        deP1 = hex(int(deS[:len(deS) - 1024], 2))
        print("\ndeP2(deP后1024位): " + deP2)
        print("\ndeP1(deP剩余部分): " + deP1)
    
        demark_r = deP1
        demark_P1 = MD4_Realize.MD4(demark_r)
        print("\ndeP1的md4值: " + demark_P1)
        demark_r = str(hex(int(demark_P1, 16) ^ int(deP2, 16)))
        demark_P1 = MD4_Realize.MD4(demark_r)
        print("\nr的md4值: " + demark_P1)
        Last_M = str(hex(int(deP1, 16) ^ int(demark_P1, 16)))
        print("\n解密结果M: " + binascii.a2b_hex(Last_M[2:]).decode("utf8"))
    
        easygui.msgbox("\n\n复原的1024位值r:\n" + bin(int(demark_r, 16))
                       + "\n\n解密结果:" + binascii.a2b_hex(Last_M[2:]).decode("utf8"))
    
    输入值M: abcdefg
    
    1024位随机数r: 0010010100110100100001010111001011101110100010111001000011111011011101110001101010001010111110101010011101110011101000111110011100101001010101001111111010101001011011110101000101101000111110100011000110011010000011111111110001010101010011000101001000100110011111011100101000001001110100100101101110101001111000011011000010000100111000101001000100010100111010001011101110001101111011011001110100100111010110000111010000110001000100101110011000110001111100010101111000100100011100101101001100010110000000001110101100000111101001010111111011110011100101111001011110010101011001111111111101100100101101001100001111000101110001000001001101010011110110011010100110001101100011011011011001000110111010100110001101001101110101000011101101100100111110101101111110000010101110010110011111100011101111100111101111100111010000100111000001101100001000111000111100100001110000100110111100110111111100101011111101010000111010001001011000100011111001110011001101100101000000100110101001011100101110111101000110001001000101010101001001101111
    
    输入值M的ascii值: b'61626364656667'
    
    r的md4值: ebc978722af2bf6eb9fc505c63e6c46f
    
    P1的md4值: a91dc46963752f5cb5f7da5305836c8d
    
    明文P=(P1+P2): 0xebc978722af2bf6eb99d323f0783a20825348572ee8b90fb771a8afaa773a3e72954fea96f5168fa319a0ffc554c52267dca09d25ba9e1b084e29114e8bb8ded9d2758743112e631f15e2472d31600eb07a57ef397979567ff64b4c3c5c41353d9a98d8db646ea634dd43b64fadf82b967e3be7be742706c238f21c26f37f2bff9f5524a84464a5edfab61828c963ee2
    
    大素数p = 168995677594036943498896698249502579045415356147450286903574977915675215654000852466242837180568368549600306461919095156035850147291191251838345423003548737288250427664794031697769270068290742307294644975782315875706815176748955712747679225674789516554407102487179525812178429394677953163553303283966837950227
    q = 73250114511939221297189302708624091354575379476811068897570041621344734046574044427415715091676742616301137831925511472461697934230365993146217113253076136386575575868816429181422361239620593954716878229091392314316476106540409390466346705287246245765228049884691190461308813988563356306637349832642629018559
    
    n = p * q: 12378952735785967421587876705989141498268850112196988040049473122006332676906044151498263826692270309125082373057093260664066396610236677683178624141001666648197090648303849825916354930186572209641520317512055055334099206541249675660097014166164940637694313192602999978844377200322202173154177984637778469358230375803525955958820029213002877725482468824045354087099096215852070204795481708079214127782986770087379200735916520872486000023245277376434002562642631172704562868269846650086718216208821320277688012375175773547390602961590412662108816162610739104457309428194480238546108099867035541068483564120972301262893
    
    φ(n) = (p - 1) * (q - 1): 12378952735785967421587876705989141498268850112196988040049473122006332676906044151498263826692270309125082373057093260664066396610236677683178624141001666648197090648303849825916354930186572209641520317512055055334099206541249675660097014166164940637694313192602999978844377200322202173154177984637778469357988130011419979794023943212044751055082478088421092731297951196315050255094906811185555575510741658921477756442071914243988451941723720131449440026386006299029736864736236189207526584900909984015676489170302065357367311678301047558894790231648703342137674275822609522272620856483794231598292911004362834294108
    
    私钥e: 17340019
    公钥d = reverseMod(e, φ(n)): 3072319204072453737306343653935533481312293926073614447951005853992407696592808146082889511413838773453536217334645343450150591445038853551083491317503107325825170520927981475375745031992517559985687240594442119595767725477701532242869466882505815287360520420998354345053176733179117600424111042142752442111367183294624823448090872105232353129797839770752679284809699116616460835070405404257340673059447242478576903179970975361234779832989464641383953590073623511860666046606738481665429583341641154379349258756279398469749734409521008401173446126887957351830297138146414843182234886281526758355953645154096249723311
    
    密文C = p^e (mod n): 8690266636448400378269418726205003112900277567495386429375850444458447796572158361293810625657601251810086273271224889184684916388080176766082690914051978067113164448575992370627181527559726902006574181613169007119234241584141129232711724255030558269342107190042881333739463284002233531205884969841267759982973947856931594586837269247202551775754985743907003991510094180725864546441495718014205230230577847231955254544873833080804873567927270581462454129765764632587975848718924619129646770469418420759534049239294802332121683853607786861658169111933815543554011449161898568916832755658480102315358426226624792795099
    
    解密后明文deP = C^d (mod n): 56342340711826069541413772838184518837709350913150351018793773491775814688941635351710013086668389205376906521762156595155945044663082632323832546315089294869517263981313583862309801851905854642025977283238207101665880369615651380303339690747636683744518917750681305477070052587129682828817201369349285188210863135129756680686281991497547712446178
    
    deP2(deP后1024位): 0x25348572ee8b90fb771a8afaa773a3e72954fea96f5168fa319a0ffc554c52267dca09d25ba9e1b084e29114e8bb8ded9d2758743112e631f15e2472d31600eb07a57ef397979567ff64b4c3c5c41353d9a98d8db646ea634dd43b64fadf82b967e3be7be742706c238f21c26f37f2bff9f5524a84464a5edfab61828c963ee2
    
    deP1(deP剩余部分): 0xebc978722af2bf6eb99d323f0783a208
    
    deP1的md4值: a91dc46963752f5cb5f7da5305836c8d
    
    r的md4值: ebc978722af2bf6eb9fc505c63e6c46f
    
    解密结果M: abcdefg
    

    相关文章

      网友评论

        本文标题:NJUPT【信息安全综合实验】

        本文链接:https://www.haomeiwen.com/subject/glklprtx.html