java代码如下
文件
ASEUtils.java package com.paic.yzt.dmps.common.utils; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.StringUtils; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; /** * @Auther: LI LIN 073 * @Date: 2019/8/12 09:51 * @Description: */ public class AESUtils { private static final String KEY_ALGORITHM = "AES"; private static final String CHAR_SET = "UTF-8"; /** * AES的密钥长度 */ private static final Integer SECRET_KEY_LENGTH = 128; /** * 加密算法 * "/算法/模式/补码方式" */ private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding"; public static String encrypt(String content, String password) { try { SecretKey key = getSecretKey(password); //创建一个实现指定转换的 Cipher对象,该转换由指定的提供程序提供。 Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] byteContent = content.getBytes(CHAR_SET); byte[] cryptograph = cipher.doFinal(byteContent); return new String(Base64.encodeBase64(cryptograph)); } catch (Exception e) { e.printStackTrace(); } return null; } public static String decrypt(String cryptograph, String password) { try { SecretKey key = getSecretKey(password); Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, key); byte[] content = cipher.doFinal(Base64.decodeBase64(cryptograph)); return new String(content,CHAR_SET); } catch (Exception e) { e.printStackTrace(); } return null; } private static SecretKey getSecretKey(String password) throws Exception { if (org.apache.commons.lang.StringUtils.isBlank(password)) { throw new NullPointerException("key not is null"); } SecretKeySpec keySpec = null; try { //"AES":请求的密钥算法的标准名称 KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM); //256:密钥生成参数;securerandom:密钥生成器的随机源 //SecureRandom securerandom = new SecureRandom(tohash256Deal(password)); SecureRandom securerandom = SecureRandom.getInstance("SHA1PRNG"); securerandom.setSeed(tohash256Deal(password)); kgen.init(SECRET_KEY_LENGTH, securerandom); //生成秘密(对称)密钥 SecretKey secretKey = kgen.generateKey(); //返回基本编码格式的密钥 byte[] enCodeFormat = secretKey.getEncoded(); //根据给定的字节数组构造一个密钥。enCodeFormat:密钥内容;"AES":与给定的密钥内容相关联的密钥算法的名称 keySpec = new SecretKeySpec(enCodeFormat, KEY_ALGORITHM); } catch (NoSuchAlgorithmException ex) { throw new NoSuchAlgorithmException(); } return keySpec; } private static byte[] tohash256Deal(String datastr) { try { MessageDigest digester=MessageDigest.getInstance("SHA-256"); digester.update(datastr.getBytes()); byte[] hex=digester.digest(); return hex; } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e.getMessage()); } } public static void main(String[] args){ String password="123abc"; String content="15067179625"; String cryptograph = encrypt(content,password); System.out.println("加密后:"+cryptograph); String decrypt = decrypt(cryptograph,password); System.out.println("解密后:"+decrypt); } }
————————————————————————————-
因为java端不是单纯的做的aes 加密, 而是将 key 又多做了一次sha256 hash
网上一直找不到sha256,自己盲测了很久终于摸索出了能匹配上java 的php代码
classAesUtil { /** * *@paramstring$string需要加密的字符串 *@paramstring$key密钥 *@returnstring */ public static function encrypt($string,$key){ //对接java,服务商做的AES加密通过SHA1PRNG算法(只要password一样,每次生成的数组都是一样的),Java的加密源码翻译php如下: //$key=substr(openssl_digest(openssl_digest($key,'sha256',true),'sha1',true),0,16); //$key=openssl_digest(openssl_digest($key,'sha256',true),'sha256',true); $key=openssl_digest($key,'sha256',true); //$key=hash("sha256",$key); $key=openssl_digest(openssl_digest($key,'sha1',true),'sha1',true); //var_dump($keys=bin2hex($key)); $key=substr($key,0,16); //openssl_encrypt加密不同Mcrypt,对秘钥长度要求,超出16加密结果不变 $data=openssl_encrypt($string,'AES-128-ECB',$key,OPENSSL_RAW_DATA); $data=base64_encode($data); return$data; } /** *@paramstring$string需要解密的字符串 *@paramstring$key密钥 *@returnstring */ public static function decrypt($string,$key){ //对接java,服务商做的AES加密通过SHA1PRNG算法(只要password一样,每次生成的数组都是一样的),Java的加密源码翻译php如下: //原始算法是不需要做sha256的,这里是因为java端在原始key基础上做了一次混淆运算 $key=openssl_digest($key,'sha256',true); //$key=hash("sha256",$key); $key=openssl_digest(openssl_digest($key,'sha1',true),'sha1',true); //var_dump($keys=bin2hex($key)); $key=substr($key,0,16); $decrypted=openssl_decrypt(base64_decode($string),'AES-128-ECB',$key,OPENSSL_RAW_DATA); return$decrypted; } }