admin管理员组文章数量:1794759
php7 aes 对接java aes SHA1PRNG算法
前提: 在实际开发过程中,跨平台跨语言api接口签名算法肯定是常有的事情。这里主要解释说的是php7 aes签名对接java aes签名。把开发过程中遇到的坑整理出来, 首先贴上java代码,java主要要注意key种子,
import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.logging.Level; import java.util.logging.Logger; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; /** * @version V1.0 * @desc AES 加密工具类 */ public class AESUtil { private static final String DEFAULT_CHARSET = "UTF-8"; private static final String KEY = "KE0yS1GcqQ823TatPYMLbwOmu7NZXHJI"; private static final String KEY_ALGORITHM = "AES"; private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//默认的加密算法 /** * AES 加密操作 * * @param content 待加密内容 * @param password 加密密码 * @return 返回Base64转码后的加密数据 */ public static String encrypt(String content, String password) { try { Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器 byte[] byteContent = content.getBytes(DEFAULT_CHARSET); cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));// 初始化为加密模式的密码器 byte[] result = cipher.doFinal(byteContent);// 加密 return parseByte2HexStr(result);//通过hex转码返回 } catch (Exception ex) { Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex); } return null; } /** * AES 解密操作 * * @param content * @param password * @return */ public static String decrypt(String content, String password) { try { //实例化 Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); //使用密钥初始化,设置为解密模式 cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password)); //执行操作 byte[] result = cipher.doFinal(parseHexStr2Byte(content)); return new String(result, DEFAULT_CHARSET); } catch (Exception ex) { Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex); } return null; } /** * 生成加密秘钥 * * @return */ private static SecretKeySpec getSecretKey(final String password) { //返回生成指定算法密钥生成器的 KeyGenerator 对象 KeyGenerator kg = null; try { kg = KeyGenerator.getInstance(KEY_ALGORITHM); SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" ); secureRandom.setSeed(password.getBytes()); //AES 要求密钥长度为 128 // kg.init(128, new SecureRandom(password.getBytes())); kg.init(128, secureRandom); //生成一个密钥 SecretKey secretKey = kg.generateKey(); //System.out.println(secretKey); return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥 } catch (NoSuchAlgorithmException ex) { Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex); } return null; } /** * 将二进制转换成16进制 * * @param buf * @return */ public static String parseByte2HexStr(byte buf[]) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < buf.length; i++) { String hex = Integer.toHexString(buf[i] & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } sb.append(hex.toUpperCase()); } return sb.toString(); } /** * 将16进制转换为二进制 * * @param hexStr * @return */ public static byte[] parseHexStr2Byte(String hexStr) { if (hexStr.length() < 1) { return null; } byte[] result = new byte[hexStr.length() / 2]; for (int i = 0; i < hexStr.length() / 2; i++) { int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16); int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16); result[i] = (byte) (high * 16 + low); } return result; } public static void main(String[] args) { String content = "idaddy0000000001KE0yS1GcqQ823TatPYMLbwOmu7NZXHJI111111"; System.out.println("加密前:" + content); String encrypt = AESUtil.encrypt(content, KEY); System.out.println("加密后:" + encrypt); System.out.println("解密后:"+AESUtil.decrypt(encrypt, KEY)); } } 结果: 加密前:123abc 加密后:ED4FFA53B4F3AE8277DEB8A4D313508E 解密后:123abcphp代码:
/** * * @author ran * */ class AES { /** * * @param string $string 需要加密的字符串 * @param string $key 密钥 * @return string */ public static function encrypt($string, $key) { // 对接java,服务商做的AES加密通过SHA1PRNG算法(只要password一样,每次生成的数组都是一样的),Java的加密源码翻译php如下: $key = substr(openssl_digest(openssl_digest($key, 'sha1', true), 'sha1', true), 0, 16); // openssl_encrypt 加密不同Mcrypt,对秘钥长度要求,超出16加密结果不变 $data = openssl_encrypt($string, 'AES-128-ECB', $key, OPENSSL_RAW_DATA); $data = strtolower(bin2hex($data)); return $data; } /** * @param string $string 需要解密的字符串 * @param string $key 密钥 * @return string */ public static function decrypt($string, $key) { // 对接java,服务商做的AES加密通过SHA1PRNG算法(只要password一样,每次生成的数组都是一样的),Java的加密源码翻译php如下: $key = substr(openssl_digest(openssl_digest($key, 'sha1', true), 'sha1', true), 0, 16); $decrypted = openssl_decrypt(hex2bin($string), 'AES-128-ECB', $key, OPENSSL_RAW_DATA); return $decrypted; } } $encrypt = AES::encrypt('123abc', 'g87y65ki6e8p93av8zjdrtfdrtgdwetd'); $decrypt = AES::decrypt($encrypt, 'g87y65ki6e8p93av8zjdrtfdrtgdwetd'); echo "加密后:".$encrypt."\\n"; echo "解密:".$decrypt; 加密后:ed4ffa53b4f3ae8277deb8a4d313508e 解密:123abcSecureRandom解析
版权声明:本文标题:php7 aes 对接java aes SHA1PRNG算法 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1686932269a119624.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论