目前一个系统(java开发的)上将加密的用户名和密码传递到另一个系统(PHP开发的),约定了java使用AES加密,php在获得加密的用户名和密码后,进行解密。
java代码:
package com.wondersgroup.common.decrypt.utils;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* Created by smart on 2015/8/17.
*/
public class Encrypt {
// 密匙
private static String DEFAULTKEY = "你的16位秘钥";
// 偏移量
private static String IVPARAMETER = "0102030405060708";
// 加密
public static String execute(String sSrc) throws Exception {
if (sSrc == null) {
return null;
}
return encrypt(sSrc, DEFAULTKEY);
}
private static String encrypt(byte[] sSrc, String sKey) throws Exception {
if (sKey == null || sSrc == null) {
return null;
}
return byte2hex(encryptByte(sSrc, sKey)).toLowerCase();
}
private static String encrypt(String sSrc, String sKey) throws Exception {
if (sKey == null || sSrc == null) {
return null;
}
return encrypt(sSrc.getBytes(), sKey);
}
private static byte[] encryptByte(byte[] sSrc, String sKey) throws Exception {
if (sKey == null || sSrc == null) {
return null;
}
// 判断Key是否为16位
if (sKey.length() != 16) {
return null;
}
byte[] raw = sKey.getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(IVPARAMETER.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
return cipher.doFinal(sSrc);
}
private static byte[] hex2byte(String strhex) {
if (strhex == null) {
return null;
}
int l = strhex.length();
if (l % 2 == 1) {
return null;
}
byte[] b = new byte[l / 2];
for (int i = 0; i != l / 2; i++) {
b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2), 16);
}
return b;
}
private static String byte2hex(byte[] b) {
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1) {
hs = hs + "0" + stmp;
} else {
hs = hs + stmp;
}
}
return hs.toUpperCase();
}
public static void main(String[] arg) {
try {
System.out.println(execute("hujunyu"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.wondersgroup.common.decrypt.utils;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* Created by smart on 2015/8/17.
*/
public class Decrypt {
//密匙
private static String DEFAULTKEY = "你的16位秘钥";
//偏移量
private static String IVPARAMETER = "0102030405060708";
public static String execute(String sSrc) throws Exception {
if ( sSrc==null) {
return null;
}
return decrypt(sSrc, DEFAULTKEY);
}
// 解密
private static String decrypt(byte[] sSrc, String sKey) throws Exception {
if (sKey == null || sSrc==null) {
return null;
}
return new String( decryptByte( sSrc, sKey));
}
private static byte[] decryptByte(byte[] sSrc, String sKey) throws Exception {
try {
// 判断Key是否正确
if (sKey == null || sSrc==null) {
return null;
}
// 判断Key是否为16位
if (sKey.length() != 16) {
return null;
}
byte[] raw = sKey.getBytes();// "ASCII"
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(IVPARAMETER.getBytes());
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
try {
return cipher.doFinal(sSrc);
} catch (Exception e) {
return null;
}
} catch (Exception ex) {
return null;
}
}
private static String decrypt(String sSrc, String sKey) throws Exception {
if (sKey == null || sSrc==null) {
return null;
}
return decrypt( hex2byte(sSrc), sKey);
}
private static byte[] hex2byte(String strhex) {
if (strhex == null) {
return null;
}
int l = strhex.length();
if (l % 2 == 1) {
return null;
}
byte[] b = new byte[l / 2];
for (int i = 0; i != l / 2; i++) {
b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2), 16);
}
return b;
}
private static String byte2hex(byte[] b) {
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1) {
hs = hs + "0" + stmp;
} else {
hs = hs + stmp;
}
}
return hs.toUpperCase();
}
public static void main(String[] arg) {
try {
System.out.println(execute("55a280077e82db68806ce77fe9602a7c"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
php代码:
/**
* java/php对应的AES/CBC/PKCS5Padding模式 加密解密
*/
class Crypt {
/**
* [$cipher 加密模式]
* @var [type]
*/
private $cipher = MCRYPT_RIJNDAEL_128;
private $mode = MCRYPT_MODE_CBC;
/**
* [$key 密匙]
* @var string
*/
private $secret_key = '你的16位秘钥';
/**
* [$iv 偏移量]
* @var string
*/
private $iv = '0102030405060708';
function setCipher($cipher=''){
$cipher && $this->cipher = $cipher;
}
function setMode($mode=''){
$mode && $this->mode = $mode;
}
function setSecretKey($secret_key=''){
$secret_key && $this->secret_key = $secret_key;
}
function setIv($iv=''){
$iv && $this->iv = $iv;
}
//加密
function encrypt($str)
{
$size = mcrypt_get_block_size ( MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC );
$str = $this->pkcs5Pad ( $str, $size );
$data=mcrypt_cbc(MCRYPT_RIJNDAEL_128, $this->secret_key, $str, MCRYPT_ENCRYPT, $this->iv);
//bin2hex() 函数把 ASCII 字符的字符串转换为十六进制值
$data=strtolower(bin2hex($data));
return $data;
}
//解密
function decrypt($str)
{
$str = $this->hex2bin( strtolower($str));
$str = mcrypt_cbc(MCRYPT_RIJNDAEL_128, $this->secret_key, $str, MCRYPT_DECRYPT, $this->iv );
$str = $this->pkcs5Unpad( $str );
return $str;
}
//bin2hex还原
private function hex2bin($hexData)
{
$binData = "";
for($i = 0; $i < strlen ( $hexData ); $i += 2)
{
$binData .= chr(hexdec(substr($hexData, $i, 2)));
}
return $binData;
}
//PKCS5Padding
private function pkcs5Pad($text, $blocksize)
{
$pad = $blocksize - (strlen ( $text ) % $blocksize);
return $text . str_repeat ( chr ( $pad ), $pad );
}
private function pkcs5Unpad($text)
{
$pad = ord ( $text {strlen ( $text ) - 1} );
if ($pad > strlen ( $text ))
return false;
if (strspn ( $text, chr ( $pad ), strlen ( $text ) - $pad ) != $pad)
return false;
return substr ( $text, 0, - 1 * $pad );
}
}
?>
例如明文:admin,加密后就是4327f7a3c4ad5e1121f12eca79d958ac(注:加密的结果与你的秘钥有关)
无论java和php的AES加密出来的结果都一致。