• Python/Java AES加解密方法互转


    背景介绍

    公司的接口有签名校验,请求头中包含了请求的时间戳,所以这种接口必须动态入参,否则无法请求成功。

    层层加密方法嵌套中,最为棘手的就是AES加/解密的方法。

    倒不是说AES本身加密方法有多复杂,而是两种IDE的AES第三方包存在小部分差异。

    Java中AES加/解密的填充方式是封装过的,而Python的AES就需要自己去定义填充方式。

    查看了Java的AES封装方法的源代码,发现默认采用是pack5padding的填充方式。

    在知道原理后,其实用Python去构造这种填充方式并不难。

    好了,b话不多说,直接上代码。

    正文

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    """
    @File:blog_test_code.py    
    @E-mail:364942727@qq.com
    @Time:2020/9/8 10:08 下午 
    @Author:Nobita   
    @Version:1.0   
    @Desciption:None
    """
    
    import base64
    import requests
    from Crypto.Cipher import AES
    from urllib import parse
    
    
    class MyHash(object):
        def __init__(self):
            """
            :param mode: AES加密模式
            """
            self.mode = AES.MODE_ECB
    
        def My_Aes_Encrypt(self, key, msg):
            """
            Aes 算法加密 ( MODE = AES.MODE_ECB;无VI偏移量;)
            :param key: 需加密的密钥
            :param msg: 需加密的字符串
            :return:
            """
            self.key = key
            self.BS = len(key)
            self.pad = lambda s: s + (self.BS - len(s) % self.BS) * chr(self.BS - len(s) % self.BS)
            Cryptor = AES.new(self.key.encode("utf8"), self.mode)
            self.ciphertext = Cryptor.encrypt(bytes(self.pad(msg), encoding="utf8"))
            # AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题,使用base64编码
            bin_encrypt_result = base64.b64encode(self.ciphertext)  # 输出的是二进制Unicode编码
            return bin_encrypt_result.decode('utf8')
    
        def My_Aes_Decrypt(self, key, msg):
            """
            Aes 算法解密 ( MODE = AES.MODE_ECB;无VI偏移量;)
            :param key: 需解密的密钥
            :param msg: 需解密的字符串
            :return:
            """
            self.key = key
            self.BS = len(key)
            self.unpad = lambda s: s[0:-ord(s[-1:])]
            decode = base64.b64decode(msg)
            Cryptor = AES.new(self.key.encode("utf8"), self.mode)
            self.plain_text = Cryptor.decrypt(decode)
            bin_decrypt_result = self.unpad(self.plain_text)  # 输出的是二进制Unicode编码
            return bin_decrypt_result.decode('utf8')
    
        def My_Aes(self, key, msg):
            """
            Java 加/解密工具类接口
            :param key: 需加密的密钥
            :param msg: 需加密的字符串
            :return: 加密后的字符
            """
            # 调用本地AES_jar包接口
            url = 'http://127.0.0.1:4271/aes/encrypt'
            payload = {
                "psw": key,
                "content": msg
            }
            r = requests.post(url=url, data=payload)
            res = r.json()['Data']
            return res
    
    
    helo = MyHash()
    
    if __name__ == '__main__':
        print('--------------------------------------Python-AES加/解密部分--------------------------------------')
        Aes_Key = "WuMlCJRN8zO886dw"
        Aes_Encrypt_msg = "<FPXX><NSRSBH>330201999999868</NSRSBH><DDLSH>3302019999998684221</DDLSH></FPXX><FPXX><NSRSBH>330201999999868</NSRSBH>330201999999868</NSRSBH>"
        res_Aes_Encrypt = helo.My_Aes_Encrypt(Aes_Key, Aes_Encrypt_msg)
        print('Aes加密前字符串:{},
    Aes加密结果:{}'.format(Aes_Encrypt_msg, res_Aes_Encrypt))
        Aes_Decrypt_msg = "hhCWnmDtU1NxQlXiE+LMiRozGLJpbu2P/2hraeHuWUQdSUtwMmwlRlPzIJqI+lbilCOe9NU3jCm6ZcelKH3eaUie36oiU4X8S94ujyhlP/qL9mKXl4oqlQo+jZzvR2DnMn45V7v3dMQ21D97sdZQvB12t9W/O2wDzBMoKKBcqIeWiJybq/MSoGBkrmOzvs1F"
        res_Aes_Decryot = helo.My_Aes_Decrypt(Aes_Key, Aes_Decrypt_msg)
        print('Aes解密前字符串:{},
    Aes解密解果:{}'.format(Aes_Decrypt_msg, res_Aes_Decryot))
        print('--------------------------------------Java工具类-AES加/解密部分--------------------------------------')
        Java_Encrypt_result = helo.My_Aes(Aes_Key, Aes_Encrypt_msg)
        print('Java Aes加密接口加密后的结果:{}'.format(Java_Encrypt_result))

    从代码中,我们清晰的能看到,我拿自己用Python写的AES加/解密算法和本地的api调用接口在进行比较。

    这个api接口是一个工具类jar包,关于AES加/解密算法的。

    下面附上Pycharm运行结果图:

    为了比较结果更加直观,再贴一张Beyond Compare的对比图:

    结束语

    遇到难以攻克的问题时,的确让人很不爽。之前这个AES加/解密jar包部署在一台虚拟服务器里面,

    公司这两天网络波动+三天两头停电,这虚拟服务器也跟着挂掉,我的“命运”也被安排了。。。。

    现在总算是可以独立开来了。。。这feel倍儿爽!

     

    作者:Nobita Chen

    -----------------------------------------------

    慢慢的,你总会发现,你的努力没有白费。

  • 相关阅读:
    jquery点击添加样式,再点击取出样式
    mongodb固定集合,建立管理员安全验证
    mongodb账号安全操作
    关于新闻,在线编辑器建表时此字段一定要为text
    创建外键表时同一个数据库中外键的名字不能用同一个
    a标签鼠标经过,字颜色和下划线的颜色都变红
    zend 快捷键
    mongodb 的安装和使用
    pdo文字水印类,验证码类,缩略图类,logo类
    erlang通讯解析浮点数的一些问题
  • 原文地址:https://www.cnblogs.com/chenshengkai/p/13636129.html
Copyright © 2020-2023  润新知