• 记python实现RSA加密登录


    项目测试中发现登录的账号密码表单是明文传输的,开发修复了之后,接口脚本因为要用到Cookies,又不想手动去复制Cookies,就只能吧公钥拿出来自己实现登录了

    一、分析加密过程

    查看网页源码

    可以看到这里登录方法直接写在源码里面了,下面直接看看登录做了什么操作

    查看登录实现过程

    得出下面几个信息:

    1. 登录接口/api/account/login
    2. 登录的json为:{'ciphertext': ciphertext}
      a. ciphertext是rsaEncryption(loginInfo)的返回值
      b. logininfo是一个类似于json的字符串 (可能还想对密码进行加密之后再处理的,又被注释掉了)
    {
        "account": this.form.account,
        // password: Base64.encode(this.form.password)
        "password": this.form.password
    }
    
    1. rsaEncryption很显然就是个rsa的加密方法了,看下具体的实现
      果然就是JSEncrypt设置完公钥之后把上面的logininfo串直接加密,然后又做了一次Base64加密

    既然知道了过程,并且也拿到了公钥,就开始撸码吧!

    二、开始撸码

    1. 网上找了python实现rsa加密的库Crypto,但是下载不下来,查了资料才知道
    pip install pycryptodome
    
    1. 下载下来之后到site-packages中把crypto的首字母大写,改为Crypto
    2. 下面就是实现过程
    import base64
    from Crypto.Cipher import PKCS1_v1_5 as Cipher_pksc1_v1_5
    from Crypto.PublicKey import RSA
    
    def _encrpt(string, public_key):
        rsakey = RSA.importKey(public_key)  # 读取公钥
        cipher = Cipher_pksc1_v1_5.new(rsakey)
        # 因为encryptor.encrypt方法其内部就实现了加密再次Base64加密的过程,所以这里实际是通过下面的1和2完成了JSEncrypt的加密方法
        encrypt_text = cipher.encrypt(string.encode())  # 1.对账号密码组成的字符串加密
        cipher_text_tmp = base64.b64encode(encrypt_text)  # 2.对加密后的字符串base64加密
        # 源码除了encryptor.encrypt加密外,又一次对密文进行了Base64加密,所以我们这里也再次加密
        cipher_text = base64.b64encode(cipher_text_tmp)  
        return cipher_text.decode()
    
    
    def gen_body(account, pwd, public_key=None):
        '''根据账号密码生成请求的body然后调用_encrpt方法加密'''
        if not public_key: public_key = 'MIGfMA0GxxxxxxxxxxEBAQUAA4GNADCBiQKBgQCFa8mE++++++++++hMrwZ7KORiOnNCVbtb7Rcnjw9Pxxxx++xxabG6QL0G2++++xxxx++JH6Q8zEQNfZ9THbFhW+BqH920D+++++++++++kG0ZCwE0jrIcxbGCZVH3OBuSZNH++++xxxx++WX1NHHDDMwSOS3PqFJ+BVOmlzeH2QIDAQAB'
        key = '-----BEGIN PUBLIC KEY-----
    ' + public_key + '
    -----END PUBLIC KEY-----'
        encrypt_res = _encrpt("{'account': '%s','password':'%s'}" % (account, pwd), key)
        return {'ciphertext': encrypt_res}
    

    因为是为了给我的接口调用,所以这里写了gen_body方法,支持账号、密码、公钥自定义传参,不必过度关注。所以本质上python实现JSEncrypt的加密方法过程其实就是:

    import base64
    from Crypto.Cipher import PKCS1_v1_5 as Cipher_pksc1_v1_5
    from Crypto.PublicKey import RSA
    
    
    def encrpt(string):
        public_key = 'MIGfMA0GxxxxxxxxxxEBAQUAA4GNADCBiQKBgQCFa8mE++++++++++hMrwZ7KORiOnNCVbtb7Rcnjw9Pxxxx++xxabG6QL0G2++++xxxx++JH6Q8zEQNfZ9THbFhW+BqH920D+++++++++++kG0ZCwE0jrIcxbGCZVH3OBuSZNH++++xxxx++WX1NHHDDMwSOS3PqFJ+BVOmlzeH2QIDAQAB'
        key = '-----BEGIN PUBLIC KEY-----
    ' + public_key + '
    -----END PUBLIC KEY-----'
        rsakey = RSA.importKey(key)
        cipher = Cipher_pksc1_v1_5.new(rsakey)
        encrypt_text = cipher.encrypt(string.encode())
        cipher_text = base64.b64encode(encrypt_text)
        return cipher_text.decode()
    
  • 相关阅读:
    linux下修改Mysql的字符编码方式
    创建XMPP工程步骤
    ClickOnce清单签名取消后依然读取证书的问题
    FxCop卸载后依然生成文件夹的问题
    使用了旧版nuget的.net项目在git中的问题
    CorelDraw X8 破解激活问题
    ASUS T100TA 换屏要记
    百度SMS SDK for .Net
    网易闪电邮
    《The Practice and Theory of Bolshevism》的笔记-第114页
  • 原文地址:https://www.cnblogs.com/wjlv/p/14618136.html
Copyright © 2020-2023  润新知