zoukankan      html  css  js  c++  java
  • python3 AES加密解密

    参考博客:https://blog.csdn.net/weixin_42068117/article/details/80084034 

      工作中开发人员用的是Java,但是写mock用的是Python,所以Java的加密解密算法转Python遇到了不少坑。下面以AES算法为例说明一下。

    Java加密:

     1 /**
     2      * aes加密-128位
     3      * 
     4      */
     5     public static  String AesEncrypt(String content ,String key){
     6         if (StringUtils.isEmpty(key) || key.length() != 16) {
     7             throw new RuntimeException("密钥长度为16位");
     8         }
     9         try {
    10             String iv = key;
    11             Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    12             int blockSize = cipher.getBlockSize();
    13             byte[] dataBytes = content.getBytes("utf-8");
    14             int plaintextLength = dataBytes.length;
    15             if (plaintextLength % blockSize != 0) {
    16                 plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
    17             }
    18             byte[] plaintext = new byte[plaintextLength];
    19             System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
    20             SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
    21             IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
    22             cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
    23             byte[] encrypted = cipher.doFinal(plaintext);
    24             return byte2Hex(encrypted);
    25 
    26         } catch (Exception e) {
    27             throw new RuntimeException("aes加密发生错误", e);
    28         }
    29     }

    Java解密:

     1     // ==Aes加解密==================================================================
     2     /**
     3      * aes解密-128位
     4      */
     5     public static String AesDecrypt(String encryptContent, String password) {
     6         if (StringUtils.isEmpty(password) || password.length() != 16) {
     7             throw new RuntimeException("密钥长度为16位");
     8         }
     9         try {
    10             String key = password;
    11             String iv = password;
    12             byte[] encrypted1 = hex2Bytes(encryptContent);
    13             Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    14             SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
    15             IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
    16             cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
    17             byte[] original = cipher.doFinal(encrypted1);
    18             return new String(original,"UTF-8").trim();
    19         } catch (Exception e) {
    20             e.printStackTrace();
    21             throw new RuntimeException("aes解密发生错误", e);
    22         }
    23     }

    对应Python加密:

     1 def aes_encrypt(data, key):
     2     """aes加密函数,如果data不是16的倍数【加密文本data必须为16的倍数!】,那就补足为16的倍数
     3     :param key:
     4     :param data:
     5     """
     6     cipher = AES.new(key, AES.MODE_CBC, key)  # 设置AES加密模式 此处设置为CBC模式
     7     block_size = AES.block_size
     8     # 判断data是不是16的倍数,如果不是用b''补足
     9     if len(data) % block_size != 0:
    10         add = block_size - (len(data) % block_size)
    11     else:
    12         add = 0
    13     data += b'' * add
    14     encrypted = cipher.encrypt(data)  # aes加密
    15     result = binascii.b2a_hex(encrypted)  # b2a_hex encode  将二进制转换成16进制
    16     return result

    Python解密:

    1 def aes_decode(data, key):
    2     """aes解密
    3     :param key:
    4     :param data:
    5     """
    6     cipher = AES.new(key, AES.MODE_CBC, key)
    7     result2 = binascii.a2b_hex(data)  # 十六进制还原成二进制
    8     decrypted = cipher.decrypt(result2)
    9     return decrypted.rstrip(b'')  # 解密完成后将加密时添加的多余字符''删除

      从Java加密的代码可以看出使用的是AES的CBC、128位模式,对应的Python加密也需要相同的模式,这里模式一定不要搞错,否则加密的结果就不一样了。

      加密的时候遇到一个比较坑的问题,就是Python加密时用的方法AES.new有三个参数,第一个参数是密钥,第二个是模式,但是第三个参数就有点蒙了,之前在网上搜的结果是需要设置一个16位的字符,可以设置为b'0000000000000000'。但是加密后结果不对,这个参数不可以随便设置,最后又回过头来看了看Java的代码,发现第三个参数和第一个参数设置的值是一样的。。。

      还有个地方需要注意一下,就是Java算法中最后将字符串转换成16进制了,所以转换成Python的时候也需要转换成16进制。

      解密的时候算法同上理。

      最后像这种Java转Python的算法,一定要看清楚Java的每一步算法的处理方法,否则就坑大了。

    以上

  • 相关阅读:
    旋转卡壳(1)求凸包(点集)直径 poj 2187
    求解平面最近点对的问题
    java中的内部类初识
    java中的多重继承
    ObjectiveC中的Protocols
    Mac中配置java的src.jar
    Mac OS X Lion无线网络问题
    Xcode中修改默认文件头部注释
    全文索引查询和like查询对比
    获取Repeater选中行索引
  • 原文地址:https://www.cnblogs.com/sammy1989/p/9663517.html
Copyright © 2011-2022 走看看