前言

有些公司对接口的安全要求比较高,传参数的时候,不会明文的传输,先对接口加密,返回的数据也加密返回。

目前比较常见的加密方式是AES/CBC/pkcs7padding。

AES五种加密模式

在AES加密时,一般使用了“AES/ECB/NoPadding”或“AES/ECB/PKCS5padding” 或 “AES/ECB/PKCS5padding” 的模式

使用AES加密的ECB模式,显式指定加密算法为:CBC或CFB模式,可带上PKCS5Padding填充。AES密钥长度最少是128位,推荐使用256位

AES-ECB模式加密在加密和解密是需要一个初始化向量(Initialization Vector, IV),在每次加密之前或者解密之后,使用初始化向量与明文或密文异或。

分组密码有五种工作体制:

1.电码本模式(Electronic Codebook Book (ECB));

2.密码分组链接模式(Cipher Block Chaining (CBC));

3.计算器模式(Counter (CTR));

4.密码反馈模式(Cipher FeedBack (CFB));

5.输出反馈模式(Output FeedBack (OFB))

AES算法是典型的【对称加密算法】,所谓对称加密,就是加密和解密的秘钥是一样的

JAVA加密

一般我们做接口自动化测试的时候,接口都是java写的,所以先得了解下java的加密方式。知道java对应的加密方式了,才能用python找到对应的解药!

/**

*

* @author ngh

* AES128 算法

*

* CBC 模式

*

* PKCS7Padding 填充模式

*

* CBC模式需要添加一个参数iv

*

* 介于java 不支持PKCS7Padding,只支持PKCS5Padding 但是PKCS7Padding 和 PKCS5Padding 没有什么区别

* 要实现在java端用PKCS7Padding填充,需要用到bouncycastle组件来实现

*/

public class AES {

// 算法名称

final String KEY_ALGORITHM = "AES";

// 加解密算法/模式/填充方式

final String algorithmStr = "AES/CBC/PKCS7Padding";

//

private Key key;

private Cipher cipher;

boolean isInited = false;

byte[] iv = { 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38 };

public void init(byte[] keyBytes) {

// 如果密钥不足16位,那么就补足. 这个if 中的内容很重要

int base = 16;

if (keyBytes.length % base != 0) {

int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);

byte[] temp = new byte[groups * base];

Arrays.fill(temp, (byte) 0);

System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);

keyBytes = temp;

}

// 初始化

Security.addProvider(new BouncyCastleProvider());

// 转化成JAVA的密钥格式

key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);

try {

// 初始化cipher

cipher = Cipher.getInstance(algorithmStr, "BC");

} catch (NoSuchAlgorithmException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (NoSuchPaddingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (NoSuchProviderException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

/**

* 加密方法

*

* @param content

* 要加密的字符串

* @param keyBytes

* 加密密钥

* @return

*/

public byte[] encrypt(byte[] content, byte[] keyBytes) {

byte[] encryptedText = null;

init(keyBytes);

System.out.println("IV:" + new String(iv));

try {

cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));

encryptedText = cipher.doFinal(content);

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return encryptedText;

}

/**

* 解密方法

*

* @param encryptedData

* 要解密的字符串

* @param keyBytes

* 解密密钥

* @return

*/

public byte[] decrypt(byte[] encryptedData, byte[] keyBytes) {

byte[] encryptedText = null;

init(keyBytes);

System.out.println("IV:" + new String(iv));

try {

cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));

encryptedText = cipher.doFinal(encryptedData);

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return encryptedText;

}

}

测试

ublic class Test {

public static void main(String[] args) {

AES aes = new AES();

// 加解密 密钥

byte[] keybytes = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38 };

String content = "1";

// 加密字符串

System.out.println("加密前的:" + content);

System.out.println("加密密钥:" + new String(keybytes));

// 加密方法

byte[] enc = aes.encrypt(content.getBytes(), keybytes);

System.out.println("加密后的内容:" + new String(Hex.encode(enc)));

// 解密方法

byte[] dec = aes.decrypt(enc, keybytes);

System.out.println("解密后的内容:" + new String(dec));

}

测试结果

测试结果:

加密前的:1

加密密钥:12345678

IV:0102030405060708

加密后的内容:b59227d86200d7fedfb8418a59a8eea9

IV:0102030405060708

解密后的内容:1

python加密

从上面的这一段JAVA代码中,我们需要知道的关键信息是,加密方式:AES/CBC/PKCS7Padding

iv偏移量 byte[] iv = { 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38 }

0x30 就是16进制的0, 所以iv = b'0102030405060708', iv一般是16位

秘钥key虽然上面测试的key是12345678,但是key一般是16位,所以它上面有个if判断不足16位的时候,用\0去填充

那么key应该是:12345678\0\0\0\0\0\0\0\0

python代码 AES/CBC/pkcs7padding 加解密

from cryptography.hazmat.primitives import padding

from cryptography.hazmat.primitives.ciphers import algorithms

from Crypto.Cipher import AES

from binascii import b2a_hex, a2b_hex

import json

'''

AES/CBC/PKCS7Padding 加密解密

环境需求:

pip3 install pycryptodome

'''

class PrpCrypt(object):

def __init__(self, key='0000000000000000'):

self.key = key.encode('utf-8')

self.mode = AES.MODE_CBC

self.iv = b'0102030405060708'

# block_size 128位

# 加密函数,如果text不足16位就用空格补足为16位,

# 如果大于16但是不是16的倍数,那就补足为16的倍数。

def encrypt(self, text):

cryptor = AES.new(self.key, self.mode, self.iv)

text = text.encode('utf-8')

# 这里密钥key 长度必须为16(AES-128),24(AES-192),或者32 (AES-256)Bytes 长度

# 目前AES-128 足够目前使用

text=self.pkcs7_padding(text)

self.ciphertext = cryptor.encrypt(text)

# 因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题

# 所以这里统一把加密后的字符串转化为16进制字符串

return b2a_hex(self.ciphertext).decode().upper()

@staticmethod

def pkcs7_padding(data):

if not isinstance(data, bytes):

data = data.encode()

padder = padding.PKCS7(algorithms.AES.block_size).padder()

padded_data = padder.update(data) + padder.finalize()

return padded_data

@staticmethod

def pkcs7_unpadding(padded_data):

unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()

data = unpadder.update(padded_data)

try:

uppadded_data = data + unpadder.finalize()

except ValueError:

raise Exception('无效的加密信息!')

else:

return uppadded_data

# 解密后,去掉补足的空格用strip() 去掉

def decrypt(self, text):

# 偏移量'iv'

cryptor = AES.new(self.key, self.mode, self.iv)

plain_text = cryptor.decrypt(a2b_hex(text))

# return plain_text.rstrip('\0')

return bytes.decode(plain_text).rstrip("\x01").\

rstrip("\x02").rstrip("\x03").rstrip("\x04").rstrip("\x05").\

rstrip("\x06").rstrip("\x07").rstrip("\x08").rstrip("\x09").\

rstrip("\x0a").rstrip("\x0b").rstrip("\x0c").rstrip("\x0d").\

rstrip("\x0e").rstrip("\x0f").rstrip("\x10")

def dict_json(self, d):

'''python字典转json字符串, 去掉一些空格'''

j = json.dumps(d).replace('": ', '":').replace(', "', ',"').replace(", {", ",{")

return j

# 加解密

if __name__ == '__main__':

import json

pc = PrpCrypt('12345678\0\0\0\0\0\0\0\0') # 初始化密钥

a = "1"

print("加密前:%s" % a)

b = pc.encrypt(a)

print("解密后:%s" % b)

print("大写变小写:%s" % b.lower())

最后运行结果

加密前:1

解密后:B59227D86200D7FEDFB8418A59A8EEA9

大写变小写:b59227d86200d7fedfb8418a59a8eea9

python aes padding_python笔记43-加解密AES/CBC/pkcs7padding相关推荐

  1. [crypto]-01-对称加解密AES原理概念详解

    1.对称加解密 术语:P是明文,C是密文,K是密钥,E是加密算法,D是解密算 (1).常用的对称加解密有哪些? (2).加解密的模式 [ecb]这种模式是将整个明文分成若干段相同的小段,然后对每一小段 ...

  2. AES实现后端参数加解密

    AES实现后端参数加解密 前言 介绍 Start 引入依赖 编写AES加解密工具类 自定义注解 编写请求数据解密 ControllerAdvice 编写返回数据加密 ControllerAdvice ...

  3. Qt写的超级方便的编码转换器、加解密AES、RSA、MD5、SHA、网页编码

    Qt彻底解决乱码问题,各种编码转换工具 Qt写的超级方便的编码转换器.加解密AES.RSA.MD5.SHA.网页编码 一键把内容转换成GBK.UTF-8.UTF-16FE.UTF-16BE.GB231 ...

  4. 基于C++的DES的EBC电子密码本加解密,CBC密码分组链接思想,以及相关流程图

    CBC模式的DES加解密 一.实验内容 学习并完成对称加解密中的DES加解密以及CBC模式的DEC加解密. 二.实验原理 2.1 DES加解密原理 DES算法是一种最通用的对称密钥算法,因为算法本身是 ...

  5. 前端CryptoJS和Java后端数据互相加解密(AES)

    目录 一.序言 二.关于前端CryptoJS 1.CryptoJS简单介绍 2.加密和填充模式选择 3.前端AES加解密示例 (1) cryptoutils工具类 (2) 测试用例 (3) 加解密后输 ...

  6. golang 的AES加解密 (CBC/ECB/CFB 模式)

    golang的AES加密和解密的三种模式实现(CBC/ECB/CFB) package mainimport ("bytes""crypto/aes"" ...

  7. 国密算法:利用python进行sm4算法的加解密,对称密钥

    本篇利用python中的gmssl库进行sm4算法的加解密演示. 国密算法sm4特点: 密钥长度:16bytes(128bits) 分组长度和密钥长度均为128bits: 是对称加密算法:分为ecb模 ...

  8. delphi7aes加密解密与java互转_跨语言(java vs python vs nodejs)的RSA加解密问题探讨

    多次被问到这样的问题: java服务端的rsa加密操作已经完成,返回一个16进制的字符串给python平台,但是在python进行私钥解密的时候发现行不通.... 前端python加密,后端用java ...

  9. node 加密解密模块_跨语言(java vs python vs nodejs)的RSA加解密问题探讨

    多次被问到这样的问题: java服务端的rsa加密操作已经完成,返回一个16进制的字符串给python平台,但是在python进行私钥解密的时候发现行不通.... 前端python加密,后端用java ...

最新文章

  1. 22张深度学习精炼图笔记总结
  2. ISA2006标准版配置导入企业版
  3. AliOS Things KV组件的写平衡特性
  4. Cassandra 单机入门例子——有索引
  5. 一个一元二次方程求解编程引申的两个知识点(abs和fabs的区别以及浮点数比较相等)...
  6. gRPC学习记录(一)--概念性知识
  7. 风险平价策略python代码_风险平价组合(risk parity)理论与实践
  8. BZOJ #3166. [Heoi2013]Alo(可持久化trie树+set)
  9. ERP项目需要持续的呵护
  10. 如何在java中实现线程_用代码说话:如何在Java中实现线程
  11. mysql字段是否存在_mysql怎么查询字段是否存在?
  12. 磨刀不误砍柴工,ORAchk健康检查好帮手
  13. 新西兰计算机预科学费,新西兰留学预科学费
  14. 什么是Automata(I): Web 3.0的最后一块拼图
  15. Longhorn云原生文件存储
  16. SSL2706 2017年8月17日提高组T2 考试(贪心)
  17. 洛谷 CF7E Defining Macros 题解
  18. node之request模块
  19. 北邮通信土著--非技术路线备忘录
  20. 憎恨之心最强套装攻略_憎恨之心新手刷BOSS攻略 最强武器介绍[多图]

热门文章

  1. SQLite FTS5使用小技巧
  2. Xamarin.Forms XAML控件的公共属性
  3. 负载均衡探测器lbd
  4. iOS10 UI教程管理层次结构
  5. Xamarin.Android提示找不到mono.Android.Support.v4
  6. Unity 4.x 2D游戏开发基础教程
  7. matlab演示系统,基于Matlab的通信原理演示系统的设计与应用
  8. 一级二级标题_考二级造价师有啥要求?
  9. python超多数据柱状图_Python快速生成可视化,Excel数据再多也不怕!
  10. 计算机组成原理第3版谢树煜,计算机组成原理(第3版)