求助贴: python 与 java的接口之争

诸葛老刘 2020-07-30 04:26:36
场景:
1. 对方公司提供了接口开发文档, 在文档中说明数据是通过DES加密+base64编码的方式传输的, 并且还贴心的给出DES加密的模块(JAVA写的, 代码后面贴上),提供的key是20位的.

问题描述:
1. 我用python开发对应的接口, 用pyDes模块加密, 在加密过程中提示: key必须是8字节的.

预解决过程:
1. pyDes模块文档,提到KEY须是8个字节.
2. 网上找到的python的pyDes与java的DES加解密相关的解决方案中,有的提到KEY须是8位的, 有的示例KEY本身就是8位的
3. 求助对方公司, 一天了,还没理我.

所以求助网上大佬:
1. 问题的焦点: 对方给出的KEY是20位的, 而我需要8位的KEY. 怎么办?
2. 研究对方这个java模块的时候, 发现第130到137这些行会对KEY进行处理, 看各位大佬能否验证是否会将KEY从20个字节转为8个字节? 以及处理的规则是怎样的.

以下是对方文档给出的DES加密模块

package com.ab.mediation.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class DesUtil {

private final static String DES = "DES";

public static void main(String[] args) throws Exception {
String tDoc = "";// 请求报文
String encoding = "GBK";
// 将函数参数赋给本地参数
String path = "D:\\11140399001500000835.xml";
// String path = "F:\\testxml\\requestAppPolInp881.xml";
String path1 = path;
// 初始化文件对象f
File f = new File(path1);
// 初始化读数据流对象reader
InputStreamReader reader = new InputStreamReader(new FileInputStream(
path1), encoding);
// 根据f文件长度初始化字符串数据c[]
char c[] = new char[(int) (f.length())];
// 取到字符串长度,并将文件f内容写入数组c
int length = reader.read(c);
// 逐字节将字符串数组c[],赋给变量tDoc
for (int i = 0; i < length; i++) {
tDoc = tDoc + c[i];
}
// System.out.println(tDoc);

String key = "12dc293d43db3b237849";
System.out.println(encrypt(tDoc, key));
System.out.println(decrypt(encrypt(tDoc, key), key));

}

/**
* Description 根据键值进行加密
*
* @param data
* @param key
* 加密键byte数组
* @return
* @throws Exception
*/
public static String encrypt(String data, String key) throws Exception {
byte[] bt = encrypt(data.getBytes(), key.getBytes());
String strs = new BASE64Encoder().encode(bt);
return strs;
}

/**
* 指定字符编码方式并加密
* @param data
* @param key
* @param encoding
* @return
* @throws Exception
*/
public static String encrypt(String data, String key, String encoding) throws Exception {
byte[] bt = encrypt(data.getBytes(encoding), key.getBytes());
String strs = new BASE64Encoder().encode(bt);
return strs;
}

/**
* Description 根据键值进行解密
*
* @param data
* @param key
* 加密键byte数组
* @return
* @throws IOException
* @throws Exception
*/
public static String decrypt(String data, String key) throws IOException,
Exception {
if (data == null)
return null;
BASE64Decoder decoder = new BASE64Decoder();
byte[] buf = decoder.decodeBuffer(data);
byte[] bt = decrypt(buf, key.getBytes());
return new String(bt);
}

/**
* 根据键值解密并返回指定编码方式字符串
* @param data
* @param key
* @param encoding
* @return
* @throws IOException
* @throws Exception
*/
public static String decrypt(String data, String key, String encoding) throws IOException,
Exception {
if (data == null)
return null;
BASE64Decoder decoder = new BASE64Decoder();
byte[] buf = decoder.decodeBuffer(data);
byte[] bt = decrypt(buf, key.getBytes());
return new String(bt, encoding);
}

/**
* Description 根据键值进行加密
*
* @param data
* @param key
* 加密键byte数组
* @return
* @throws Exception
*/
private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
// 生成一个可信任的随机数源
SecureRandom sr = new SecureRandom();

// 从原始密钥数据创建DESKeySpec对象
DESKeySpec dks = new DESKeySpec(key);

// 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
SecretKey securekey = keyFactory.generateSecret(dks);

// Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance(DES);

// 用密钥初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);

return cipher.doFinal(data);
}

/**
* Description 根据键值进行解密
*
* @param data
* @param key
* 加密键byte数组
* @return
* @throws Exception
*/
private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
// 生成一个可信任的随机数源
SecureRandom sr = new SecureRandom();

// 从原始密钥数据创建DESKeySpec对象
DESKeySpec dks = new DESKeySpec(key);

// 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
SecretKey securekey = keyFactory.generateSecret(dks);

// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance(DES);

// 用密钥初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, securekey, sr);

return cipher.doFinal(data);
}
}
...全文
2175 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
诸葛老刘 2020-07-31
  • 打赏
  • 举报
回复
你太牛逼了 哈哈
RockeyCui 2020-07-31
  • 打赏
  • 举报
回复
重点在这一句: // 从原始密钥数据创建DESKeySpec对象 DESKeySpec dks = new DESKeySpec(key); 来看看 java 官方说明: 想不到吧,只取前8个字节,哈哈哈哈哈哈哈嗝。。。我自己也测试了一下,key 前8个字节一致的话,它的代码 加密出的结果是一样的。你把他提供的 key 取前8个字节用 pydes 试试吧,看看结果一不一样。

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧