哪位牛人给看看这段java代码怎么转PHP。 java做的DES加密。php这边加密java解析不了
public class DESUtil { private static byte[] iv = {1, 2, 3, 4, 5, 6, 7, 8}; private static byte[] algorithm(byte[] data, String key, int opmode) {
if(data == null) {
return null;
}
try {
IvParameterSpec zeroIv = new IvParameterSpec(iv); DESKeySpec dks = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(dks);
// 当使用其他对称加密算法时,如AES、Blowfish等算法时,用下述代码替换上述三行代码
// SecretKey secretKey = new SecretKeySpec(password.getBytes(), ALGORITHM); //Cipher cipher = Cipher.getInstance(ALGORITHM);
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(opmode, secretKey, zeroIv);
return cipher.doFinal(data);
} catch(Exception ex) {
ex.printStackTrace();
}
return null;
} /**
* DES解密
*/
public static String decrypt(String data, String key) {
byte[] temp = Base64Utils.decodeFromString(data);
byte[] bytes = algorithm(temp, key, Cipher.DECRYPT_MODE);
if(bytes != null) {
return new String(bytes);
} else {
return null;
}
} /**
* DES加密
*/
public static String encrypt(String data, String key) {
byte[] bytes = algorithm(data.getBytes(), key, Cipher.ENCRYPT_MODE);
if(bytes != null) {
return Base64Utils.encodeToString(bytes);
} else {
return null;
}
}
public static void main(String[] args) {
String url = "http://localhost:8086/airuntop-lock-client/";
String ecodeURI = DESUtil.encrypt("rest/user/login", "20160114API");
url = url+ecodeURI;
System.out.println(url);
}}
public class DESUtil { private static byte[] iv = {1, 2, 3, 4, 5, 6, 7, 8}; private static byte[] algorithm(byte[] data, String key, int opmode) {
if(data == null) {
return null;
}
try {
IvParameterSpec zeroIv = new IvParameterSpec(iv); DESKeySpec dks = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(dks);
// 当使用其他对称加密算法时,如AES、Blowfish等算法时,用下述代码替换上述三行代码
// SecretKey secretKey = new SecretKeySpec(password.getBytes(), ALGORITHM); //Cipher cipher = Cipher.getInstance(ALGORITHM);
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(opmode, secretKey, zeroIv);
return cipher.doFinal(data);
} catch(Exception ex) {
ex.printStackTrace();
}
return null;
} /**
* DES解密
*/
public static String decrypt(String data, String key) {
byte[] temp = Base64Utils.decodeFromString(data);
byte[] bytes = algorithm(temp, key, Cipher.DECRYPT_MODE);
if(bytes != null) {
return new String(bytes);
} else {
return null;
}
} /**
* DES加密
*/
public static String encrypt(String data, String key) {
byte[] bytes = algorithm(data.getBytes(), key, Cipher.ENCRYPT_MODE);
if(bytes != null) {
return Base64Utils.encodeToString(bytes);
} else {
return null;
}
}
public static void main(String[] args) {
String url = "http://localhost:8086/airuntop-lock-client/";
String ecodeURI = DESUtil.encrypt("rest/user/login", "20160114API");
url = url+ecodeURI;
System.out.println(url);
}}
但php算出的结果始终跟java端不同,经过测试和下断点排查,发现是变量位数搞的鬼,java是32位算法,而我服务器上的环境是64位的变量,只要更换到32位环境就匹配上了
进一步研究,发现是按位左移操作 << 出现的问题:如果移动后数字超过了4字节,在32位环境下会抹掉超出的部分,而在64位环境却保存了下来,最后结果就不一样了
我不太确定你碰到的是不是这个问题,你试试我的函数,代替你原先的php代码中的 << 操作符
public function bitMoveLeft32($int, $x) {
//$int << $x;
$x = abs($x);
$bin = decbin($int << $x);
$bin = substr($bin, -32);
$res = bindec($bin);
$max = 4294967296;
if ($res > $max / 2) {
$res = $res - $max;
}
return $res;
}
2、你是想要我搭个 java 环境,并测试你的 java 代码的正确性?
3、由于 java 和 php 内部实现上的差异,只有一种 3DES 算法是可以与 php 对等的(不过你是 DES)
所以你不能强调 java 代码不能改
其实 java、C#、php 通用的 3DES 算法在网上是可以找到的转入正题:
byte[] iv = {1, 2, 3, 4, 5, 6, 7, 8};
你把他翻译成 php 的什么呢?
$iv = pack('C*, 1, 2, 3, 4, 5, 6, 7, 8};
$iv = "\x01\x02\x03\x04\x05\x06\x07\x08";
还是什么?
byte 是单字节无符号整数,php 没有对等的数据类型
byte 的值,对等于 php 的 ord()