PHP DES-ECB加密对接Java解密
最近公司有个业务,需要对接第三方接口,但是参数是需要加密的,对方也只提供了一个java的demo,在网上到处搜索,没有找到直接就能用的方法,后来还是跟公司的Android工程师对接出来的,在这里记录一下大致的流程。
首先说明一下对方要求的接口请求方式,格式为:http://ip:port/interface/method?data=摘要@@16进制字符串
说明:
1. 请求参数需要组合成a=1&b=2&c=3格式的参数串;
2. 摘要的生成方法为md5('a=1&b=2&c=3');
3. 16进制字符串的生成方法是将参数串进行**对称加密(DES-ECB)**后再转成16进制字符串(bin2hex函数);
对方提供的demo(java版本)如下:
public class DesUtils {
/** 默认密钥 */
private static String strDefaultKey = "seeyonssokey";
/** 加密工具 */
private Cipher encryptCipher;
/** 解密工具 */
private Cipher decryptCipher;
/**
* 加密字符串
* @param strIn 需加密的字符串
* @return 加密后的字符串
* @throws Exception
*/
public String encrypt(String strIn) throws Exception {
return byteArr2HexStr(encryptCipher.doFinal(strIn.getBytes()));
}
/**
* 解密字符串
* @param strIn 需解密的字符串
* @return 解密后的字符串
* @throws Exception
*/
public String decrypt(String strIn) throws Exception {
return new String(decryptCipher.doFinal(hexStr2ByteArr(strIn)));
}
/**
* 将 byte 数组转换为表示 16 进制值的字符串, 如: byte[]{8,18} 转换为: 0813 , 和 public static
* byte[] hexStr2ByteArr(String strIn) 互为可逆的转换过程
* @param arrB 需要转换的 byte 数组
* @return 转换后的字符串
* @throws Exception 本方法不处理任何异常,所有异常全部抛出
*/
public static String byteArr2HexStr(byte[] arrB) throws Exception {
int iLen = arrB.length;
// 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍
StringBuffer sb = new StringBuffer(iLen * 2);
for(int i = 0; i < iLen; i++) {
int intTmp = arrB[i];
// 把负数转换为正数
while(intTmp < 0) {
intTmp = intTmp + 256;
}
// 小于0F的数需要在前面补0
if(intTmp < 16) {
sb.append("0");
}
sb.append(Integer.toString(intTmp, 16));
}
return sb.toString();
}
/**
* 将 表 示 16 进 制 值 的 字 符 串 转 换 为 byte 数 组 , 和 public static String
* byteArr2HexStr(byte[] arrB) 互为可逆的转换过程
* @param strIn 需要转换的字符串
* @return 转换后的 byte 数组
* @throws Exception 本方法不处理任何异常,所有异常全部抛出
* @author <a href="mailto:leo841001@163.com">LiGuoQing</a>
*/
public static byte[] hexStr2ByteArr(String strIn) throws Exception {
byte[] arrB = strIn.getBytes();
int iLen = arrB.length;
// 两个字符表示一个字节,所以字节数组长度是字符串长度除以2
byte[] arrOut = new byte[iLen / 2];
for(int i = 0; i < iLen; i = i + 2) {
String strTmp = new String(arrB, i, 2);
arrOut[i / 2] = (byte)Integer.parseInt(strTmp, 16);
}
return arrOut;
}
/**
* 从指定字符串生成密钥,密钥所需的字节数组长度为 8 位 不足 8 位时后面补 0 , 超出 8 位只取前 8 位
* @param arrBTmp 构成该字符串的字节数组
* @return 生成的密钥
* @throws java.lang.Exception
*/
private static Key getKey(byte[] arrBTmp) throws Exception {
// 创建一个空的8位字节数组(默认值为0)
byte[] arrB = new byte[8];
// 将原始字节数组转换为8位
for(int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
arrB[i] = arrBTmp[i];
}
// 生成密钥
Key key = new SecretKeySpec(arrB, "DES");
return key;
}
public static String encrypt(String strIn, String secretkey) throws Exception {
Key key = getKey(secretkey.getBytes("utf-8"));
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
return byteArr2HexStr(cipher.doFinal(strIn.getBytes("utf-8")));
}
public static String decrypt(String strIn, String secretkey) throws Exception {
Key key = getKey(secretkey.getBytes("utf-8"));
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] param = cipher.doFinal(hexStr2ByteArr(strIn));
return new String(param, "utf-8");
}
}
PHP实现加密功能的的方法有两种:
- mcrypt方式(适用于php7.0以前的版本):
<?php
$text = 'a=1&b=2&c=3'; //参数串
$key = 'abcd1234'; // 密钥
echo $ret = self::encryptForDES($text , $key); //加密
/**
* 字符串加密(加密方法:DES-ECB)
* @param string $input 待加密字符串
* @param string $key 对称加密密钥
* @return string
*/
function encryptData($input, $key)
{
$size = mcrypt_get_block_size('des','ecb'); // 计算加密算法的分组大小
$input = self::pkcs5_pad($input, $size); // 对字符串进行补码
$td = mcrypt_module_open('des', '', 'ecb', '');
$iv = @mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
@mcrypt_generic_init($td, $key, $iv);
$data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$data = bin2hex($data); // 将加密后的字符串转化为16进制
return $data;
}
/**
- 对字符串进行补码
- @param string $text 原字符串
- @param string $blockSize 加密算法的分组大小
- @return string
*/
function pkcs5_pad($text, $blockSize)
{
$pad = $blockSize - (strlen($text) % $blockSize);
return $text . str_repeat(chr($pad), $pad);
}
输出为:990389f0aad8d12014ca6a45cd72cdf7
- openssl方式(适用于php7.0以后的版本):
<?php
$text = 'a=1&b=2&c=3'; // 参数串
$key = 'abcd1234'; // 密钥
echo encryptData($text, $key); // 加密
/**
* 字符串加密(加密方法:DES-ECB)
* @param string $input 待加密字符串
* @param string $key 对称加密密钥
* @return string
*/
function encryptData($input, $key)
{
$ivlen = openssl_cipher_iv_length('DES-ECB'); // 获取密码iv长度
$iv = openssl_random_pseudo_bytes($ivlen); // 生成一个伪随机字节串
$data = openssl_encrypt($input, 'DES-ECB', $key, $options=OPENSSL_RAW_DATA, $iv); // 加密
return bin2hex($data);
}
输出为:990389f0aad8d12014ca6a45cd72cdf7
原文地址:https://segmentfault.com/a/1190000016888916
PHP DES-ECB加密对接Java解密的更多相关文章
- DES c#加密后java解密
public static String byteArr2HexStr(byte[] bytIn) { StringBuilder builder = new StringBuilder(); for ...
- 利用DES,C#加密,Java解密代码
//C#加密 /// <summary> /// 进行DES加密. /// </summary> /// <param name="pToEncrypt&quo ...
- node-rsa加密,java解密调试
用NODE RSA JS 加密解密正常,用JAVA RSAUtils工具类加密解密正常.但是用node加密玩的java解密不了.原因:node默认的是 DEFAULT_ENCRYPTION_SCHEM ...
- c#加密,java解密(3DES加密)
c#代码 using System; using System.Security; using System.Security.Cryptography; using System.IO; using ...
- js前端3des加密 后台java解密
import java.security.Key; import java.security.SecureRandom; import javax.crypto.Cipher; import java ...
- 前端 js加密 后台java 解密 RSA
前端代码 : $.ajax({ type:"GET", url:"http://localhost:8084/getPulbicKey", dataType:& ...
- RSA非对称加密,使用OpenSSL生成证书,iOS加密,java解密
最近换了一份工作,工作了大概一个多月了吧.差不多得有两个月没有更新博客了吧.在新公司自己写了一个iOS的比较通用的可以架构一个中型应用的不算是框架的一个结构,并已经投入使用.哈哈 说说文章标题的相关的 ...
- python des ecb 加密 demo
# -*- coding:utf-8 -*- from pyDes import * def hexString2bytes(src): ret =[] for i in range(len(src) ...
- DES ECB 模式 JAVA PHP C# 实现 加密 解密 兼容
版本一: JAVA: import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sun.misc.BASE64Decoder; i ...
随机推荐
- Elasticsearch之重要核心概念(cluster(集群)、shards(分配)、replicas(索引副本)、recovery(据恢复或叫数据重新分布)、gateway(es索引的持久化存储方式)、discovery.zen(es的自动发现节点机制机制)、Transport(内部节点或集群与客户端的交互方式)、settings(修改索引库默认配置)和mappings)
Elasticsearch之重要核心概念如下: 1.cluster 代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的.es的一个概念就是 ...
- ibatis annotations 注解方式返回刚插入的自增长主键ID的值--转
原文地址:http://www.blogs8.cn/posts/WWpt35l mybatis提供了注解方式编写sql,省去了配置并编写xml mapper文件的麻烦,今天遇到了获取自增长主键返回值的 ...
- 为什么不建议用table进行布局
本文部分内容转载自:http://www.html5tricks.com/why-not-table-layout.html 刚刚接触html的时候,利用table进行页面布局是比较容易的.但是,在实 ...
- webpack JS 源文件
blob:https://www.xiaogezi.cn/49602f64-ee4a-4b4a-b0cf-c21aa3335614 /******/ (function(modules) { // w ...
- POJ 3617 Best Cow Line 贪心算法
Best Cow Line Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26670 Accepted: 7226 De ...
- 【原创】JMS生产者和消费者【PTP同步接收消息】
一般步骤: 请求一个JMS连接工i厂. 是用连接工厂创建连接. 启动JMS连接. 通过连接创建session. 获取一个目标. 创建一个生产者,或a.创建一个生产者,b.创建一条JMS消息并发送到目标 ...
- SpringCloud学习笔记(1)----认识微服务与SpringCloud
1. 微服务是什么? 微服务是一种由多个服务组成的集合体,它属于一种软甲架构,在微服务中,它的每个服务都是独立存在的,微服务是一种去中心化的思想. 它具有开发简单,技术栈灵活,服务独立解耦,可用性高 ...
- CDR X6设计师的福利,3折特惠!
最新消息称,即日起CorelDRAW官方为回馈新老用户长期以来的支持,特别推出CorelDRAW X6降价活动.目前CorelDRAW X6售价仅为2399元,照这个价格,CDR 2017 会 ...
- 线段树合并&&启发式合并笔记
这俩东西听起来很高端,实际上很好写,应用也很多~ 线段树合并 线段树合并,顾名思义,就是建立一棵新的线段树保存原有的两颗线段树的信息. 考虑如何合并,对于一个结点,如果两颗线段树都有此位置的结点,则直 ...
- C指针思考-(1)
首先记录下时间吧,@2016-08-18 23:26:22,这段时间看了同事的3本经典的书,<c缺陷和陷阱>,<c和指针>和<c专家编程>,感觉指针说的最多,多多少 ...