php des加密用java解析不了 改个模式 加个IV php密钥/IV要求都是8位
php des加密用java解析不了 Wrong IV length: must be 8 bytes long
PHP的DES加密和Java解密不兼容的问题通常是因为PHP默认使用ECB模式,而Java可能默认使用其他模式如CBC,或者使用不同的padding方式。
解决方法:
确保PHP和Java使用相同的加密模式(如CBC)和padding方式(如PKCS5Padding或NoPadding)。
确保两边使用相同的密钥和初始化向量(IV)。
以下是PHP和Java分别使用CBC模式和PKCS5Padding的示例代码:
PHP:
代码语言:javascript复制<?php
$key = '12345678'; // 密钥
$iv = '12345678'; // 初始化向量
$data = 'Data to encrypt';
$td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $key, $iv);
$encrypted = mcrypt_generic($td, $data);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
echo base64_encode($encrypted);
?>
JAVA:
代码语言:javascript复制import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class Main {
public static void main(String[] args) throws Exception {
String key = "12345678"; // 密钥
String iv = "12345678"; // 初始化向量
String data = "Data to encrypt";
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "DES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encrypted = cipher.doFinal(data.getBytes());
System.out.println(Base64.getEncoder().encodeToString(encrypted));
}
}
代码语言:javascript复制import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class Main {
public static void main(String[] args) throws Exception {
String key = "12345678"; // 密钥
String iv = "12345678"; // 初始化向量
String data = "Data to encrypt";
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "DES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encrypted = cipher.doFinal(data.getBytes());
System.out.println(Base64.getEncoder().encodeToString(encrypted));
}
}
在这两个示例中,我们都使用了CBC模式和PKCS5Padding,并且密钥和初始化向量都是固定的字符串。在实际应用中,你需要确保密钥和向量的安全性,并且在解密时使用相同的参数。
链接:des加密,url编码,url解码,des解密 DES加解密及Wrong key size错误处理
https://cloud.tencent.com/developer/article/2455804
工具类DEMO:
代码语言:javascript复制package com.example.core.mydemo.des;
import com.example.core.mydemo.MD5;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* output:原始字符串 = {"phone":"1391111","username":"张三"}
* des加密 = LHFFScjfDE1kEyz27Y4ffRb0aM98qONoW8HGHzqjCqBqX9fwlPb28w==
* url编码 = LHFFScjfDE1kEyz27Y4ffRb0aM98qONoW8HGHzqjCqBqX9fwlPb28w==
* url解码 = LHFFScjfDE1kEyz27Y4ffRb0aM98qONoW8HGHzqjCqBqX9fwlPb28w==
* 不相同
* des解密 = {"phone":"1391111","username":"张三"}
*/
public class CbcIvDesUtls {
private static String CHARSETNAME="UTF-8";
static String iv = "12345678"; // 初始化向量
/**
* DES加解密及Wrong key size错误处理
* @param key
* @return
* @throws UnsupportedEncodingException
*/
private static byte[] getKeyBytes(String key) throws UnsupportedEncodingException {
byte[] keyBytes = key.getBytes(CHARSETNAME);
if (keyBytes.length < 8) {
byte[] bytes = new byte[8];
System.arraycopy(keyBytes, 0, bytes, 0, keyBytes.length);
keyBytes = bytes;
}
return keyBytes;
}
public static String getDESStr(String str, String encryptKey, String type, String charset) throws Exception {
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(encryptKey.getBytes(), "DES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
//加密
if ("ENCRYPT".equals(type)) {
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
return Base64Encoder.encode(cipher.doFinal(str.getBytes(charset)));
}else if ("DECRYPT".equals(type)) {
byte[] encodeByte = Base64Encoder.decode(str.getBytes());
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decoder = cipher.doFinal(encodeByte);
return new String(decoder, charset);
}
return "type error";
}
public static void main(String[] args) {
//java.security.InvalidKeyException: Wrong key size
//密钥要求是8位
String encryptKey = "abcdefgh";
String type = "ENCRYPT";
String charset = "UTF-8";
String str = "{"phone":"1391111","username":"张三"}";
System.out.println("原始字符串 = " str);
try {
//des加密
String DESStr= getDESStr(str,encryptKey,type,charset);
System.out.println("des加密 = " DESStr);
// url编码
DESStr = URLEncoder.encode(DESStr,"UTF-8");
System.out.println("url编码 = " DESStr);
//url解码
String s = URLDecoder.decode(DESStr,"UTF-8");
System.out.println("url解码 = " s);
//javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
/**
* 报错原因是因为:解密字符串不是url解码后的,所以会报该错误。
*/
// System.out.println("des解密2 = " getDESStr(DESStr,encryptKey,"DECRYPT","UTF-8"));
//des解密
if(DESStr.equals(s)){
System.out.println("相同");
}else{
System.out.println("不相同");
}
System.out.println("des解密 = " getDESStr(s,encryptKey,"DECRYPT","UTF-8"));
//ENCRYPT(des加密) encode(url编码) >> decode(url解码) encrypt(des解密)
} catch (Exception e) {
e.printStackTrace();
}
}
}
代码语言:javascript复制package com.example.core.mydemo.des;
import com.example.core.mydemo.MD5;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* output:原始字符串 = {"phone":"1391111","username":"张三"}
* des加密 = LHFFScjfDE1kEyz27Y4ffRb0aM98qONoW8HGHzqjCqBqX9fwlPb28w==
* url编码 = LHFFScjfDE1kEyz27Y4ffRb0aM98qONoW8HGHzqjCqBqX9fwlPb28w==
* url解码 = LHFFScjfDE1kEyz27Y4ffRb0aM98qONoW8HGHzqjCqBqX9fwlPb28w==
* 不相同
* des解密 = {"phone":"1391111","username":"张三"}
*/
public class CbcIvDesUtls {
private static String CHARSETNAME="UTF-8";
static String iv = "12345678"; // 初始化向量
/**
* DES加解密及Wrong key size错误处理
* @param key
* @return
* @throws UnsupportedEncodingException
*/
private static byte[] getKeyBytes(String key) throws UnsupportedEncodingException {
byte[] keyBytes = key.getBytes(CHARSETNAME);
if (keyBytes.length < 8) {
byte[] bytes = new byte[8];
System.arraycopy(keyBytes, 0, bytes, 0, keyBytes.length);
keyBytes = bytes;
}
return keyBytes;
}
public static String getDESStr(String str, String encryptKey, String type, String charset) throws Exception {
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(encryptKey.getBytes(), "DES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
//加密
if ("ENCRYPT".equals(type)) {
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
return Base64Encoder.encode(cipher.doFinal(str.getBytes(charset)));
}else if ("DECRYPT".equals(type)) {
byte[] encodeByte = Base64Encoder.decode(str.getBytes());
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decoder = cipher.doFinal(encodeByte);
return new String(decoder, charset);
}
return "type error";
}
public static void main(String[] args) {
//java.security.InvalidKeyException: Wrong key size
//密钥要求是8位
String encryptKey = "abcdefgh";
String type = "ENCRYPT";
String charset = "UTF-8";
String str = "{"phone":"1391111","username":"张三"}";
System.out.println("原始字符串 = " str);
try {
//des加密
String DESStr= getDESStr(str,encryptKey,type,charset);
System.out.println("des加密 = " DESStr);
// url编码
DESStr = URLEncoder.encode(DESStr,"UTF-8");
System.out.println("url编码 = " DESStr);
//url解码
String s = URLDecoder.decode(DESStr,"UTF-8");
System.out.println("url解码 = " s);
//javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
/**
* 报错原因是因为:解密字符串不是url解码后的,所以会报该错误。
*/
// System.out.println("des解密2 = " getDESStr(DESStr,encryptKey,"DECRYPT","UTF-8"));
//des解密
if(DESStr.equals(s)){
System.out.println("相同");
}else{
System.out.println("不相同");
}
System.out.println("des解密 = " getDESStr(s,encryptKey,"DECRYPT","UTF-8"));
//ENCRYPT(des加密) encode(url编码) >> decode(url解码) encrypt(des解密)
} catch (Exception e) {
e.printStackTrace();
}
}
}
工具类DEMO简化版本:
代码语言:javascript复制package com.example.core.mydemo.des;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class IvDesTest {
public static void main(String[] args) throws Exception{
String key = "12345678"; // 密钥8位
String iv = "12345678"; // 初始化向量 Wrong IV length: must be 8 bytes long
String data = "Data to encrypt";
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "DES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
//加密
byte[] encrypted = cipher.doFinal(data.getBytes());
String encryptStr = Base64.getEncoder().encodeToString(encrypted);
System.out.println("encryptStr=" encryptStr);
//解密
byte[] encodeByte = Base64Encoder.decode(encryptStr.getBytes());
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decoder = cipher.doFinal(encodeByte);
String decryptStr = new String(decoder);
System.out.println("decryptStr=" decryptStr);
}
}
代码语言:javascript复制package com.example.core.mydemo.des;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class IvDesTest {
public static void main(String[] args) throws Exception{
String key = "12345678"; // 密钥8位
String iv = "12345678"; // 初始化向量 Wrong IV length: must be 8 bytes long
String data = "Data to encrypt";
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "DES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
//加密
byte[] encrypted = cipher.doFinal(data.getBytes());
String encryptStr = Base64.getEncoder().encodeToString(encrypted);
System.out.println("encryptStr=" encryptStr);
//解密
byte[] encodeByte = Base64Encoder.decode(encryptStr.getBytes());
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decoder = cipher.doFinal(encodeByte);
String decryptStr = new String(decoder);
System.out.println("decryptStr=" decryptStr);
}
}