当前位置: 首页 > news >正文

java加密,使用python解密 ,使用 pysm4 报 byte greater than 16的解决方法

1,业务需要,对方需要用java进行参数加密,双方约定使用的加密方法是 SM4,对方给的key是32位,并且给出了加解密的java代码。

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;/*** sm4加密算法工具类*/
public class SM4Util {static {Security.addProvider(new BouncyCastleProvider());}private static final String ENCODING = "UTF-8";public static final String ALGORITHM_NAME = "SM4";// 加密算法/分组加密模式/分组填充方式// PKCS5Padding-以8个字节为一组进行分组加密// 定义分组加密模式使用:PKCS5Paddingpublic static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";// 128-32位16进制;256-64位16进制public static final int DEFAULT_KEY_SIZE = 128;/*** 生成ECB暗号* @explain ECB模式(电子密码本模式:Electronic codebook)* @param algorithmName*            算法名称* @param mode*            模式* @param key* @return* @throws Exception*/private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key) throws Exception {Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);cipher.init(mode, sm4Key);return cipher;}/*** 自动生成密钥* @explain* @return* @throws NoSuchAlgorithmException* @throws NoSuchProviderException*/public static String generateKey() throws Exception {return generateKey(DEFAULT_KEY_SIZE);}/*** @explain* @param keySize* @return* @throws Exception*/public static String generateKey(int keySize) throws Exception {KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);kg.init(keySize, new SecureRandom());return ByteUtils.toHexString(kg.generateKey().getEncoded());}/*** sm4加密* @explain 加密模式:ECB*          密文长度不固定,会随着被加密字符串长度的变化而变化* @param hexKey*            16进制密钥(忽略大小写)* @param paramStr*            待加密字符串* @return 返回16进制的加密字符串* @throws Exception*/public static String encryptEcb(String hexKey, String paramStr) throws Exception {String cipherText = "";// 16进制字符串-->byte[]byte[] keyData = ByteUtils.fromHexString(hexKey);// String-->byte[]byte[] srcData = paramStr.getBytes(ENCODING);// 加密后的数组byte[] cipherArray = encryptEcbPadding(keyData, srcData);// byte[]-->hexStringcipherText = ByteUtils.toHexString(cipherArray);return cipherText;}/*** 加密模式之Ecb* @explain* @param key* @param data* @return* @throws Exception*/public static byte[] encryptEcbPadding(byte[] key, byte[] data) throws Exception {Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);return cipher.doFinal(data);}/*** sm4解密* @explain 解密模式:采用ECB* @param hexKey*            16进制密钥* @param cipherText*            16进制的加密字符串(忽略大小写)* @return 解密后的字符串* @throws Exception*/public static String decryptEcb(String hexKey, String cipherText) throws Exception {// 用于接收解密后的字符串String decryptStr = "";// hexString-->byte[]byte[] keyData = ByteUtils.fromHexString(hexKey);// hexString-->byte[]byte[] cipherData = ByteUtils.fromHexString(cipherText);// 解密byte[] srcData = decryptEcbPadding(keyData, cipherData);// byte[]-->StringdecryptStr = new String(srcData, ENCODING);return decryptStr;}/*** 解密* @explain* @param key* @param cipherText* @return* @throws Exception*/public static byte[] decryptEcbPadding(byte[] key, byte[] cipherText) throws Exception {Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);return cipher.doFinal(cipherText);}public static void main(String[] args) {try {String generateKey = SM4Util.generateKey();System.out.println(generateKey);String json = "mate60 nb";// 自定义的32位16进制密钥String key = "2c1f9b9388c5fc713c5ceab2af6f0f2d";String encrypted = SM4Util.encryptEcb(key, json);System.out.println(encrypted);json = SM4Util.decryptEcb(key, encrypted);System.out.println(json);} catch (Exception e) {e.printStackTrace();}}
}

2,这边用的后台程序python+flask只能用python去解密,先使用pysm4

from pysm4 import encrypt_ecb, decrypt_ecb
plain_text = '13800138000'
key = '86C63*80C2806E*1F47B8*9DE501215*'
cipher_text = encrypt_ecb(plain_text, key)plain_text == decrypt_ecb(cipher_text, key)

报  Parameter key or iv:********* byte greater than 16的错误,应该是有个地方配置key的长度。

3,但是对方也只能支持32位的方法,所以只能换方法,测试了一下,下面python方法可以完美支持32位,并且测试和java加密,python解密后也相同。

python实现sm4,ecb模式加密_python sm4_pchaoda的博客-CSDN博客

http://www.lryc.cn/news/158862.html

相关文章:

  • django后台启动CORS跨越配置
  • 异常的顶级理解
  • LinkedHashMap实现LRU缓存cache机制,Kotlin
  • Google 开源库Guava详解(集合工具类)
  • Ansys Zemax | 如何将光线追迹结果导出为IES格式
  • JSONObject 比 Map好使的地方
  • [js] 图解 event.pageX event.clientX event.offsetX getBoundingClientRect
  • VsCode备忘
  • Linux命令200例:Yum强大的包管理工具使用(常用)
  • 使用 Linux 相关知识部署博客系统
  • Linux--进程--vfork与fork区别
  • Ubuntu系统重装nvidia gpu驱动
  • Java + Selenium + Appium自动化测试
  • 【sgLazyCascader】自定义组件:基于el-cascader的懒加载级联菜单,支持异步加载子级菜单
  • 2023高教社杯数学建模E题思路模型 - 黄河水沙监测数据分析
  • 一、Linux下常用的压缩格式
  • MySQL 查询 - 排除某些字段的SQL查询,提升查询性能
  • 国产信创服务器如何进行安全可靠的文件传输?
  • ARTS第五周:S - 数据编织 Data fabric
  • 基于ArcGIS、ENVI、InVEST、FRAGSTATS等多技术融合提升环境、生态、水文、土地、土壤、农业、大气等领域的数据分析能力与项目科研水平教程
  • Spring Boot 介绍
  • mysql基于AES_ENCRYPTAES_DECRYPT实现密码的加密与解密
  • 怎么把pdf转换成jpg图片?
  • 计算机脚本的概念,如何编写、使用脚本 (Script)?
  • c语言 5.0
  • 如何配置远程访问以在外部网络中使用公司内部的OA办公系统——“cpolar内网穿透”
  • 【AI】机器学习——线性模型(线性回归)
  • 智能小车之跟随小车、避障小车原理和代码
  • 行业追踪,2023-09-07
  • Qt creator中项目的构建配置和运行设置