最近有一个需求,需要将php写的加密算法用java实现,php的代码已经有了,但是用java改写,尝试了好多久也没有成功。有知道的同学,希望不吝赐教,谢谢。
php的代码如下:
<?php
function simple_encrypt($text)
{
$key = "anything";
$vi = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $vi)));
}
function simple_decrypt($text)
{
$key = "anything";
$vi = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($text), MCRYPT_MODE_ECB, $vi));
}
$str = '12345';
$en = simple_encrypt($str);
$de = simple_decrypt($en);
var_dump($en, $de);
?>
执行结果为:
string(44) "uEJfzXHxFVIlu2KGCtToiouT/EeMeat8CHvgkN5kzA4="
string(5) "12345"
1
Septembers 2015-05-04 19:19:22 +08:00
Java和PHP,AES无非就是参数不匹配,主要就是Padding参数
|
2
ilotuo 2015-05-04 19:26:24 +08:00 via Android
丢 直接github搜 aes.java咩有
|
3
wy315700 2015-05-04 19:30:04 +08:00
ECB模式没有IV啊
CBC才有 public static String encryptWithAES(byte[] text, String key) { Cipher c = null; try { c = Cipher.getInstance("AES/ECB/PKCS7Padding"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } try { c.init(Cipher.ENCRYPT_MODE, generateAESKey(key)); } catch (InvalidKeyException e) { e.printStackTrace(); } byte[] enBytes = new byte[0]; try { enBytes = c.doFinal(text); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } String s = Utility.urlSafeBase64Enc(enBytes); return s; } public static byte[] decryptWithAES(String text, String key) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException { Cipher c = Cipher.getInstance("AES/ECB/PKCS7Padding"); c.init(Cipher.DECRYPT_MODE, generateAESKey(key)); byte[] enBytes = c.doFinal(Utility.urlSafeBase64Dec(text)); return enBytes; } public static SecretKey generateAESKey(String key){ SecretKeyFactory factory = null; byte[] tmp2; try { factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); KeySpec spec = new PBEKeySpec(key.toCharArray(), "key".getBytes(), 64, 128); SecretKey tmp = factory.generateSecret(spec); tmp2 = tmp.getEncoded(); // return secret; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } catch (InvalidKeySpecException e) { e.printStackTrace(); return null; } |
4
youxiaer OP @wy315700
恩,是CBC,我写错了,然后我用java实现,IV是32字节,执行就会报错。 java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 16 bytes long |
5
wy315700 2015-05-04 19:39:24 +08:00
@youxiaer IV是16字节的,
CBC里,IV是和密文块一样长的,AES一个Block是128位,也就是16字节, 另外,自定义IV或者固定IV都是不安全的。正确的做法应该是,生成一个随机块nonce,然后用一个独立的key加密用作IV |
6
youxiaer OP @wy315700
php 中的这个函数 mcrypt_decrypt,最后一个参数$vi 可以是32字节。其实我最想知道就是如何用java实现php的 mcrypt_decrypt函数。 string mcrypt_decrypt ( string $cipher , string $key , string $data , string $mode [, string $iv ] ) |
7
youxiaer OP @wy315700
php中这两个方法应该是下面这样的。 function simple_encrypt($text) { $key = "anything"; $vi = 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI='; $key = hash('sha256', $key, true); $vi = base64_decode($vi); return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $vi))); } function simple_decrypt($text) { $key = "anything"; $vi = 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI='; $key = hash('sha256', $key, true); $vi = base64_decode($vi); return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($text), MCRYPT_MODE_CBC, $vi)); } $str = '1234567890987654321'; $en = simple_encrypt($str); $de = simple_decrypt($en); var_dump($en, $de); 执行结果: string(44) "OgmKJ5gu4rRYB47pVV5N1GyTW5+aKNjQnx2TFYjNdUI=" string(19) "1234567890987654321" |
8
wy315700 2015-05-04 20:43:50 +08:00
@youxiaer http://www.cnblogs.com/arix04/archive/2009/06/26/1511839.html
不太清楚为什么PHP的IV是32字节的。。。难道是hex编码,就是4位用一个16进制数字。 |
9
youxiaer OP |