php des加密用java解析不了 改个模式 加个IV php密钥/IV要求都是8位
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:
<?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:
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)); } }
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://www.cnblogs.com/oktokeep/p/17917821.html
工具类DEMO:
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%3D%3D * 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(); } } }
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%3D%3D * 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简化版本:
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); } }
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); } }