zoukankan      html  css  js  c++  java
  • rsa字符串格式公钥转换python rsa库可识别的公钥形式

      在爬虫分析的时候,经常在网页上看到如下格式的rsa公钥:

    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDC7kw8r6tq43pwApYvkJ5laljaN9BZb21TAIfT/vexbobzH7Q8SUdP5uDPXEBKzOjx2L28y7Xs1d9v3tdPfKI2LR7PAzWBmDMn8riHrDDNpUpJnlAGUqJG9ooPn8j7YNpcxCa1iybOlc2kEhmJn5uwoanQq+CA6agNkqly2H4j6wIDAQAB

      对于rsa算法的公钥,我们了解到,主要有两个信息:模数(modulus)和指数(exponent)

      只有有这两个信息,我们便可以用以下代码段生成公钥,然后使用rsa库对数据进行加密

    import rsa
    
    key = rsa.PublicKey(modulus, exponent)
    print key

     现在我们需要做的就是从这段字符串中提出模数和指数.

     在研究的过程中,除了这种字符串的形式,我们看得最多的应该属于public.pem、private.pem这种文件格式的公钥私钥了.

     那么PEM这又是个什么格式呢,搜索下来,基本上都说包含什么信息然后是数据什么的,我怎么知道那些是信息,那些是数据呢?

     对比一些资料,觉得看下图基本明了(本来是有一篇很好的文章,貌似找不到链接了,只保存了一张图片)

      我们打开pem格式的文件看一下,发现

    -----BEGIN RSA PUBLIC KEY-----
    MIGJAoGBAPVZR7eov/GFh77lx2sp1FDkP63mygPAUkomwV9fPFUuajviO5038P3k
    Jhl5o14+LN8NxLuyiTzgYKSunUkvqxwkWSKHOw8EL3m6YKytk5UR+FEg8LBqPNox
    lcT9a9VH2PngbnR9WWm2ycMQBppQRC3Ci7yLIcjwgDUOrgoz6PmpAgMBAAE=
    -----END RSA PUBLIC KEY-----

      这个BEGIN和这个END中间这一段很像我们找到的这个字符串,我们把开头的字符串复制到public.pem文件的中间,然后使用以下代码加密试试:

    import rsa
    
    with open('public.pem','r') as f:
        pubkey = rsa.PublicKey.load_pkcs1(f.read().encode())
    
    message = 'cnblogs'
    crypto = rsa.encrypt(message.encode(), pubkey)
    print crypto

      这段似乎根本就会报错,而且,这个复制过去的格式也不对,原先的是有换行的,

      查询一下似乎换行也是一种信息,而我们的字符串从哪里换行根本无从得知

      那么,这个字符串和pem就没有别的联系了吗?答案是有的.

      之前就有猜测这个字符串可能是base64加密过的,那么我就解密看看:

    import base64
    
    pubkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDC7kw8r6tq43pwApYvkJ5laljaN9BZb21TAIfT/vexbobzH7Q8SUdP5uDPXEBKzOjx2L28y7Xs1d9v3tdPfKI2LR7PAzWBmDMn8riHrDDNpUpJnlAGUqJG9ooPn8j7YNpcxCa1iybOlc2kEhmJn5uwoanQq+CA6agNkqly2H4j6wIDAQAB"
    
    b64_str = base64.b64decode(pubkey)
    
    print b64_str
    print len(b64_str)

      得到一串乱码,我们把这串乱码转换成16进制

      发现结尾是"x01x00x01",10001,看多了rsa的公钥,就知道这个数,多半是exponent了.

      再看看解码后的长度,162,我们找到偏移表,发现模数的偏移位置是159,长度是3,加起来正好162

      那么说明这段字符串就是指数和模数加密过后的结果,甚至比一般的pem文件中的信息还要简单

      按照这个思路,对照偏移表我们找出指数和模数:

    # /usr/bin/python
    # encoding: utf-8
    
    import base64
    
    def str2key(s):
        # 对字符串解码
        b_str = base64.b64decode(s)
    
        if len(b_str) < 162:
            return False
    
        hex_str = ''
    
        # 按位转换成16进制
        for x in b_str:
            h = hex(ord(x))[2:]
            h = h.rjust(2, '0')
            hex_str += h
    
        # 找到模数和指数的开头结束位置
        m_start = 29 * 2
        e_start = 159 * 2
        m_len = 128 * 2
        e_len = 3 * 2
    
        modulus = hex_str[m_start:m_start + m_len]
        exponent = hex_str[e_start:e_start + e_len]
    
        return modulus,exponent
    
    if __name__ == "__main__":
    
        pubkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDC7kw8r6tq43pwApYvkJ5laljaN9BZb21TAIfT/vexbobzH7Q8SUdP5uDPXEBKzOjx2L28y7Xs1d9v3tdPfKI2LR7PAzWBmDMn8riHrDDNpUpJnlAGUqJG9ooPn8j7YNpcxCa1iybOlc2kEhmJn5uwoanQq+CA6agNkqly2H4j6wIDAQAB"
        key = str2key(pubkey)
        print key

      得到结果如下:

    ('c2ee4c3cafab6ae37a7002962f909e656a58da37d0596f6d530087d3fef7b16e86f31fb43c49474fe6e0cf5c404acce8f1d8bdbccbb5ecd5df6fded74f7ca2362d1ecf033581983327f2b887ac30cda54a499e500652a246f68a0f9fc8fb60da5cc426b58b26ce95cda41219899f9bb0a1a9d0abe080e9a80d92a972d87e23eb', '010001')

      现在我们用刚才得到的key来加密字符串:

        import rsa
    
        message = 'cnblogs'
        modulus = int(key[0], 16)
        exponent = int(key[1], 16)
        rsa_pubkey = rsa.PublicKey(modulus, exponent)
        crypto = rsa.encrypt(message, rsa_pubkey)
        b64str = base64.b64encode(crypto)
        print b64str

      就可以得到一个rsa加密,base64编码过的字符串了.

      总结一下:主要就是在一串字符串中,对照一个偏移表,提取需要的位置上的数字.

      

  • 相关阅读:
    Beta 冲刺 (2/7)
    福大软工 · 第十次作业
    Beta 冲刺(1/7)
    BETA 版冲刺前准备
    福大软工 · 第十一次作业
    Alpha 冲刺 (9/10)
    Alpha 冲刺 (8/10)
    Alpha 冲刺 (7/10)
    2017-2018-1 20155321 《信息安全系统设计基础》第十四周学习总结
    2017-2018-1 20155321 《信息安全系统设计基础》实验五——实时系统
  • 原文地址:https://www.cnblogs.com/masako/p/7660418.html
Copyright © 2011-2022 走看看