Last active
June 10, 2022 16:15
-
-
Save PhilipTang/0570750d78f25a05b6601f8310977903 to your computer and use it in GitHub Desktop.
标准的3DES加密&解密(Java 和 PHP 版)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// javac test3.java | |
// java test3 | |
import java.security.Key; | |
import javax.crypto.Cipher; | |
import javax.crypto.SecretKeyFactory; | |
import javax.crypto.spec.DESedeKeySpec; | |
import javax.crypto.spec.IvParameterSpec; | |
import sun.misc.BASE64Decoder; | |
import sun.misc.BASE64Encoder; | |
/** | |
* | |
* @author Administrator | |
*/ | |
public class STD3Des { | |
public static void main(String[] args) throws Exception { | |
byte[] key = ("f510b8737344cddbca1c8564").getBytes(); | |
// byte[] keyiv = {0x66,0x6f,0x61,0x6f,0x63,0x75,0x65,0x6e}; | |
byte[] keyiv = {'f','o','a','o','c','u','e','n'}; | |
System.out.println("\r\nkey.length:" + key.length); | |
byte[] data = "中国ABCabc1234".getBytes("UTF-8"); | |
System.out.println("ECB加密解密"); | |
byte[] str3 = des3EncodeECB(key, data); | |
byte[] str4 = ees3DecodeECB(key, str3); | |
System.out.println(new BASE64Encoder().encode(str3)); | |
System.out.println(new String(str4, "UTF-8")); | |
System.out.println("<=============>"); | |
System.out.println("CBC加密解密"); | |
byte[] str5 = des3EncodeCBC(key, keyiv, data); | |
byte[] str6 = des3DecodeCBC(key, keyiv, str5); | |
System.out.println(new BASE64Encoder().encode(str5)); | |
System.out.println(new String(str6, "UTF-8")); | |
} | |
/** | |
* ECB加密,不要IV | |
* | |
* @param key 密钥 | |
* @param data 明文 | |
* @return Base64编码的密文 | |
* @throws Exception | |
*/ | |
public static byte[] des3EncodeECB(byte[] key, byte[] data) | |
throws Exception { | |
Key deskey = null; | |
DESedeKeySpec spec = new DESedeKeySpec(key); | |
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede"); | |
deskey = keyfactory.generateSecret(spec); | |
Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding"); | |
cipher.init(Cipher.ENCRYPT_MODE, deskey); | |
byte[] bOut = cipher.doFinal(data); | |
return bOut; | |
} | |
/** | |
* ECB解密,不要IV | |
* | |
* @param key 密钥 | |
* @param data Base64编码的密文 | |
* @return 明文 | |
* @throws Exception | |
*/ | |
public static byte[] ees3DecodeECB(byte[] key, byte[] data) | |
throws Exception { | |
Key deskey = null; | |
DESedeKeySpec spec = new DESedeKeySpec(key); | |
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede"); | |
deskey = keyfactory.generateSecret(spec); | |
Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding"); | |
cipher.init(Cipher.DECRYPT_MODE, deskey); | |
byte[] bOut = cipher.doFinal(data); | |
return bOut; | |
} | |
/** | |
* CBC加密 | |
* | |
* @param key 密钥 | |
* @param keyiv IV | |
* @param data 明文 | |
* @return Base64编码的密文 | |
* @throws Exception | |
*/ | |
public static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data) | |
throws Exception { | |
Key deskey = null; | |
DESedeKeySpec spec = new DESedeKeySpec(key); | |
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede"); | |
deskey = keyfactory.generateSecret(spec); | |
Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding"); | |
IvParameterSpec ips = new IvParameterSpec(keyiv); | |
cipher.init(Cipher.ENCRYPT_MODE, deskey, ips); | |
byte[] bOut = cipher.doFinal(data); | |
return bOut; | |
} | |
/** | |
* CBC解密 | |
* | |
* @param key 密钥 | |
* @param keyiv IV | |
* @param data Base64编码的密文 | |
* @return 明文 | |
* @throws Exception | |
*/ | |
public static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data) | |
throws Exception { | |
Key deskey = null; | |
DESedeKeySpec spec = new DESedeKeySpec(key); | |
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede"); | |
deskey = keyfactory.generateSecret(spec); | |
Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding"); | |
IvParameterSpec ips = new IvParameterSpec(keyiv); | |
cipher.init(Cipher.DECRYPT_MODE, deskey, ips); | |
byte[] bOut = cipher.doFinal(data); | |
return bOut; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* 3des 对称加密解密,与 java c#兼容 | |
* $iv cbc 分组模式的偏移量,没有则使用 ecb 模式 | |
*/ | |
class STD3Des { | |
private $key = ""; | |
private $iv = ""; | |
private $mode = MCRYPT_MODE_CBC; | |
/** | |
* 构造,传递二个已经进行 base64_encode 的 KEY 与 IV | |
* | |
* @param string $key | |
* @param string $iv | |
*/ | |
function __construct($key, $iv = null) { | |
if (empty($key)) { | |
echo 'key is not valid'; | |
exit(); | |
} | |
if ($iv == null) { | |
$iv = $key; | |
$this->mode = MCRYPT_MODE_ECB; | |
} | |
$this->key = $key; | |
$this->iv = $iv; | |
} | |
/** | |
* 加密 | |
* @param <type> $value | |
* @return <type> | |
*/ | |
public function encrypt($value) { | |
$td = mcrypt_module_open(MCRYPT_3DES, '', $this->mode, ''); | |
$iv = $this->mode == MCRYPT_MODE_CBC ? base64_decode($this->iv) : mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND); | |
$value = $this->PaddingPKCS7($value); | |
//$key = base64_decode($this->key); // 对京东风控 API 不适用 | |
mcrypt_generic_init($td, $key, $iv); | |
$dec = mcrypt_generic($td, $value); | |
$ret = base64_encode($dec); | |
mcrypt_generic_deinit($td); | |
mcrypt_module_close($td); | |
return $ret; | |
} | |
/** | |
* 解密 | |
* @param <type> $value | |
* @return <type> | |
*/ | |
public function decrypt($value) { | |
$td = mcrypt_module_open(MCRYPT_3DES, '', $this->mode, ''); | |
$iv = $this->mode == MCRYPT_MODE_CBC ? base64_decode($this->iv) : mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND); | |
//$key = base64_decode($this->key); // 对京东风控 API 不适用 | |
mcrypt_generic_init($td, $key, $iv); | |
$ret = trim(mdecrypt_generic($td, base64_decode($value))); | |
$ret = $this->UnPaddingPKCS7($ret); | |
mcrypt_generic_deinit($td); | |
mcrypt_module_close($td); | |
return $ret; | |
} | |
private function PaddingPKCS7($data) { | |
$block_size = mcrypt_get_block_size('tripledes', $this->mode); | |
$padding_char = $block_size - (strlen($data) % $block_size); | |
$data .= str_repeat(chr($padding_char), $padding_char); | |
return $data; | |
} | |
private function UnPaddingPKCS7($text) { | |
$pad = ord($text{strlen($text) - 1}); | |
if ($pad > strlen($text)) { | |
return false; | |
} | |
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) { | |
return false; | |
} | |
return substr($text, 0, -1 * $pad); | |
} | |
} |
Great. Thanks.
加密或者解密的$key 应该是$this->key
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
关于调用京东风控 API 的加密解密注意项: