java、php分别实现兼容的3DES对称加密和解密
程序员文章站
2024-03-14 13:38:34
...
最近在对接别人的接口时,对方要求敏感信息传输必须进行3DES加密,并且很贴心提供了一个java Demo。可是我主力后端语言是PHP——世界上最好的语言,java处于勉强看懂的水平,要实现需求,只能踩bug过河了。万幸的是,费了大半天时间,终于解决了。国际惯例,先祭上java实现:
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
/**
* 1) 提供了 TripleDES、AES、SHA1、MD5、BASE64等加解密、编解码工具;
* 2) 可以在静态导入(import static)这个类,这样用起来更方便;
*/
public final class Crypto {
public static String code = "UTF-8";
public static final class TripleDES {
public static final String encrypt(String data, String secretKey) {
try {
// 3DES加密
byte[] encrpyted = tripleDES(Cipher.ENCRYPT_MODE, data.getBytes(code), secretKey.getBytes());
byte[] encoded = Base64.encodeBase64(encrpyted); // Base64编码
return new String(encoded);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static final String decrypt(String data, String secretKey) {
try {
byte[] decoded = Base64.decodeBase64(data); // Base64解码
byte[] decrypted = tripleDES(Cipher.DECRYPT_MODE, decoded, secretKey.getBytes());// 3DES解密
return new String(decrypted, code);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
private static byte[] tripleDES(int opmode, byte[] data, byte[] secretKey) {
return cipher("DESede", "DESede/CBC/PKCS5Padding", opmode, data, "01234567".getBytes(), secretKey);
}
}
public static final String SHA256(String data) {
try {
return DigestUtils.sha256Hex(data.getBytes(code));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static final String SHA1(String data) {
try {
return DigestUtils.sha1Hex(data.getBytes(code));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static final String MD5(String data) {
try {
return DigestUtils.md5Hex(data.getBytes(code));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static final String MD5num(String data) {
try {
return byteArrayToString(DigestUtils.md5(data.getBytes(code)));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static final class BASE64 {
public static final String encode(String data) {
try {
return Base64.encodeBase64String(data.getBytes(code));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static final String decode(String data) {
try {
return new String(Base64.decodeBase64(data), code);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
private static String byteArrayToString(byte[] b) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
resultSb.append(byteToNumString(b[i]));
}
return resultSb.toString();
}
private static String byteToNumString(byte b) {
int _b = b;
if (_b < 0) {
_b = 256 + _b;
}
return String.valueOf(_b);
}
/**
* 通用的对称加密算法
*
* @param algorithm
* , 算法名称
* @param transformation
* , 算法名称/工作模式/填充模式
* @param opmode
* :Cipher.ENCRYPT_MODE和Cipher.DECRYPT_MODE
* @param data
* , 明文或密文数据
* @param iv
* , 初始化向量
* @param secretKey
* ,**
* @return 加密或解密的结果
*/
private static final byte[] cipher(String algorithm, String transformation, int opmode, byte[] data, byte[] iv,
byte[] secretKey) {
try {
// 转换**
Key key = SecretKeyFactory.getInstance(algorithm).generateSecret(new DESedeKeySpec(secretKey));
// 转换初始化向量
IvParameterSpec spec = new IvParameterSpec(iv);
// 加密解密器
Cipher cipher = Cipher.getInstance(transformation);
cipher.init(opmode, key, spec);
// 加密解密操作
return cipher.doFinal(data);
} catch (InvalidKeyException | InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException
| IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
throw new RuntimeException(e);
}
}
}
php实现:
<?php
class TripleDES{
public function encrypt3DES($input, $key) {
// $str = self::pkcs5_pad($input, 8);
$str = $input;
if (strlen($str) % 8) {
$str = str_pad($str,strlen($str) + 8 - strlen($str) % 8, "\0");
}
// $sign = openssl_encrypt ($str, 'DES-EDE3-CBC' ,$key,OPENSSL_RAW_DATA | OPENSSL_NO_PADDING,'01234567');
$sign = openssl_encrypt ($str, 'DES-EDE3-CBC' ,$key,1,'01234567');
return base64_encode($sign);
// return $sign;
}
public function pkcs5_pad ($text, $blocksize) {
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
public function decrypt3DES($data,$method,$key,$options,$iv){
$output = openssl_decrypt($data, $method,$key,$options,$iv);
return $output;
}
}
?>
上一篇: iOS中3DES加密解密
下一篇: php 3des解密