java、php分别实现兼容的3DES对称加密和解密

it2022-05-05  114

最近在对接别人的接口时,对方要求敏感信息传输必须进行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; } } ?>

最新回复(0)