我是一名小小php开发,最近要与第三方接口对接时,发现他们是写java的,粗看能明白是什么意思,但组合起来就费劲了。
目前难题是,AES加密结果不一致。对方提供的java示例和我自己写的php得的结果不同。而且加密这块我接触比较少,有哪位大神知道怎么写php的aes加密嘛?
java示例如下:
package com.xwtech.mservice.utils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Locale;
/**
* AES加密和解密工具类
*/
public class AESUtil {
// AES密码器
// private static Cipher cipher;
// 字符串编码
private static final String KEY_CHARSET = "UTF-8";
// 算法方式
private static final String KEY_ALGORITHM = "AES";
/**
* 算法/模式/填充
*/
private static final String CIPHER_ALGORITHM_CBC = "AES/ECB/PKCS7Padding";
/**
* 私钥大小128/192/256(bits)位 即:16/24/32bytes,暂时使用128,如果扩大需要更换java/jre里面的jar包
*/
private static final Integer PRIVATE_KEY_SIZE_BIT = 256;
/**
* 加密
*
* @param secretKey 密钥:加密的规则
* @param plainText 明文:要加密的内容
* @return cipherText
* 密文:加密后的内容,如有异常返回空串:""
*/
public static byte[] encrypt(String secretKey, String plainText) throws UnsupportedEncodingException, BadPaddingException, IllegalBlockSizeException {
// 密文字符串
// 加密模式初始化参数
Cipher cipher = init(secretKey, Cipher.ENCRYPT_MODE);
// 获取加密内容的字节数组
byte[] bytePlainText = plainText.getBytes(KEY_CHARSET);
// 执行加密
byte[] byteCipherText = cipher.doFinal(bytePlainText);
return byteCipherText;
}
/**
* 加密 输出方式 十六进制的大写字符串Hex
*
* @param secretKey
* @param plainText
* @return
*/
public static String encryptHex(String secretKey, String plainText) {
String cipherText;
try {
byte[] byteCipherText = encrypt(secretKey, plainText);
cipherText = new String(Hex.encode(byteCipherText));
System.out.println(cipherText);
// cipherText = Base64.encodeBase64String(byteCipherText);
} catch (Exception e) {
throw new RuntimeException("AES 加密异常", e);
}
return cipherText;
}
/**
* 解密
*
* @param secretKey 密钥:加密的规则 16位
* @param byteCipherText 密文:加密后的内容,即需要解密的内容
* @return plainText
* 明文:解密后的内容即加密前的内容,如有异常返回空串:""
*/
public static String decrypt(String secretKey, byte[] byteCipherText) throws BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
// 明文字符串
Cipher cipher = init(secretKey, Cipher.DECRYPT_MODE);
// 解密
byte[] bytePlainText = cipher.doFinal(byteCipherText);
String plainText = new String(bytePlainText, KEY_CHARSET);
return plainText;
}
/**
* 解密
*
* @param secretKey
* @param cipherText
* @return
*/
public static String decryptHex(String secretKey, String cipherText) {
String plainText;
try {
byte[] byteCipherText = Hex.decode(cipherText);
plainText = decrypt(secretKey, byteCipherText);
} catch (Exception e) {
throw new RuntimeException("AES 解密失败!", e);
}
return plainText;
}
/**
* 初始化参数
*
* @param secretKey 密钥:加密的规则 16位
* @param mode 加密模式:加密or解密
*/
private static Cipher init(String secretKey, int mode) {
try {
//NoSuchProviderException: No such provider: BC
Security.addProvider(new BouncyCastleProvider());
// 防止Linux下生成随机key
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
// SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");
secureRandom.setSeed(secretKey.getBytes());
// 获取key生成器
KeyGenerator keygen = KeyGenerator.getInstance(KEY_ALGORITHM);
// keygen.init(PRIVATE_KEY_SIZE_BIT, secureRandom);
keygen.init(PRIVATE_KEY_SIZE_BIT);
// 获得原始对称密钥的字节数组
byte[] raw = Hex.decode(secretKey.toLowerCase(Locale.US));
// byte[] raw = secretKey.getBytes();
// 根据字节数组生成AES内部密钥
SecretKeySpec key = new SecretKeySpec(raw, KEY_ALGORITHM);
// 根据指定算法"AES/CBC/PKCS5Padding"实例化密码器
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC, "BC");
//ECB 不需要偏移量
// IvParameterSpec iv = new IvParameterSpec(secretKey.getBytes());
// System.out.println("iv:" + new String(iv.getIV()));
// cipher.init(mode, key, iv);
cipher.init(mode, key);
return cipher;
} catch (Exception e) {
throw new RuntimeException("ASEUtil init error", e);
}
}
public static void main(String[] args) throws Exception {
String secretKey = "a4b71cc1aa242737a9b2627471bdb666";
String text = "{\n" +
"\t\"serialNumber\": \"123987864182\",\n" +
"\t\"channelId\": \"3\",\n" +
"\t\"transferId\":\"153913940636224886\",\n"+
"\t\"compName\": \"EMS\",\n" +
"\t\"compNum\": \"1298787428378\",\n" +
"\t\"respTime\": \"201802061604\"\n" +
"}";
String miwen = encryptHex(secretKey, text);
System.out.println("密文为:" + miwen);
String mingwen = decryptHex(secretKey, miwen);
System.out.println("明文为:" + mingwen);
}
}