如何把以下 java AES-128-CBC java md5加密方法法改为 php 的实现

2003人阅读
AES加密 PHP和java进行aes加密对接 数据加密
最近做了一个需求,要和第三方的系统对接,其中数据传输要用对方的要求进行aes加密,之前没接触过aes加密,后来研究了一把,蛋碎了一地,为了避免下次蛋碎,特总结一下:
下面是第三方给的java加密demo
publicclassAESPlus {
&* @paramstrKey密匙
&* @paramstrIn待价密串
&* @return
&* @throws&Exception
publicstatic&String encrypt(String strKey, String strIn) {
Cipher cipher = Cipher.getInstance(&AES/CBC/PKCS5Padding&);
cipher.init(
Cipher.ENCRYPT_MODE,
newSecretKeySpec(strKey.getBytes(), &AES&),
newIvParameterSpec(newbyte[16])//初始化16空字节 &&
byte[] encrypted = cipher.doFinal(strIn.getBytes());
returnnew&BASE64Encoder().encode(encrypted);
} catch&(Exception e) {
Util.err(e);
return&&&;
对应php aes加密如下:
& & &* This was AES-128 / CBC / PKCS5Padding
& & &* return base64_encode string
& & &* @author Terry
& & &* @param string $plaintext
& & &* @param string $key
& & &* @return string
& & public static function AesEncrypt($plaintext,$key = null)
& & & & $plaintext = trim($plaintext);
& & & & if ($plaintext == '') return '';
& & & & $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
& & & & //PKCS5Padding
& & & & $padding = $size - strlen($plaintext) % $
& & & & // 添加Padding
& & & & $plaintext .= str_repeat(chr($padding), $padding);
& & & & $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
& & & & $key=self::substr($key, 0, mcrypt_enc_get_key_size($module));
& & & & $iv = str_repeat(&\0&, $size); & & &//此处蛋碎一地啊,java里面的16个空数组对应的是\0.由于不懂java,这个地方百度了很久,后来是请教主管才搞定的。
& & & & /* Intialize encryption */
& & & & mcrypt_generic_init($module, $key, $iv);
& & & & /* Encrypt data */
& & & & $encrypted = mcrypt_generic($module, $plaintext);
& & & & /* Terminate encryption handler */
& & & & mcrypt_generic_deinit($module);
& & & & mcrypt_module_close($module);
& & & & return base64_encode($encrypted);
& & &* Returns the length of the given string.
& & &* If available uses the multibyte string function mb_strlen.
& & &* @param string $string the string being measured for length
& & &* @return integer the length of the string
& & private static function strlen($string)
& & & & return extension_loaded('mbstring') ? mb_strlen($string,'8bit') : strlen($string);
& & &* Returns the portion of string specified by the start and length parameters.
& & &* If available uses the multibyte string function mb_substr
& & &* @param string $string the input string. Must be one character or longer.
& & &* @param integer $start the starting position
& & &* @param integer $length the desired portion length
& & &* @return string the extracted part of string, or FALSE on failure or an empty string.
& & private static function substr($string,$start,$length)
& & & & return extension_loaded('mbstring') ? mb_substr($string,$start,$length,'8bit') : substr($string,$start,$length);
& & &* This was AES-128 / CBC / PKCS5Padding
& & &* @author Terry
& & &* @param string $encrypted & & base64_encode encrypted string
& & &* @param string $key
& & &* @throws CException
& & &* @return string
& & public static function AesDecrypt($encrypted, $key = null)
& & & & if ($encrypted == '') return '';
& & & & $ciphertext_dec = base64_decode($encrypted);
& & & & $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
& & & & $key=self::substr($key, 0, mcrypt_enc_get_key_size($module));
& & & & $iv = str_repeat(&\0&, 16); & &//解密的初始化向量要和加密时一样。
& & & & /* Initialize encryption module for decryption */
& & & & mcrypt_generic_init($module, $key, $iv);
& & & & /* Decrypt encrypted string */
& & & & $decrypted = mdecrypt_generic($module, $ciphertext_dec);
& & & & /* Terminate decryption handle and close module */
& & & & mcrypt_generic_deinit($module);
& & & & mcrypt_module_close($module);
& & & & $a = rtrim($decrypted,&\0&);
& & & & return rtrim($decrypted,&\0&);
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:14433次
排名:千里之外
原创:31篇
(1)(1)(1)(1)(2)(1)(10)(1)(1)(4)(6)(5)(2)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'如何把以下 java AES-128-CBC 加密方法改为 php 的实现
13:58:15 +08:00 · 1546 次点击
第三方 API 需要用到的加密,他们就一个 java demo ,需要自己改为 php 来实现,但我试了好久都没办法得到相同的结果
Java 的源码
public static String encrypt(String input, String key){
byte[] crypted =
SecretKeySpec skey = new SecretKeySpec(getHash("MD5", key), "AES");
IvParameterSpec iv = new IvParameterSpec(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skey, iv);
crypted = cipher.doFinal(input.getBytes());
return new String(Base64.encodeBase64(crypted));
private static byte[] getHash(String algorithm, String text) {
byte[] bytes = text.getBytes("UTF-8");
final MessageDigest digest = MessageDigest.getInstance(algorithm);
digest.update(bytes);
return digest.digest();
} catch (final Exception ex) {
throw new RuntimeException(ex.getMessage());
我自己做 PHP 的实现
public static function encrypt($input, $key) {
$key = hash('md5', $key, true);
$iv = '0000';
return openssl_encrypt($input, 'aes-128-cbc', $key, 0, $iv);
key:"cb247aa57c2a"
input:"1234"
result in java:UfczMtIAm8ewSuIGRdPTDQ==
result in PHP:wd/OTHoIXwgHGDHcj8OTgg==
如果换成把 cipher 方法换成 ECB 结果就相同了。。
mcrypt_generic 和 mcrypt_encrypt 这两种实现,但结果和 openssl_encrypt 一模一样
求大大指教
第 1 条附言 &·&
14:50:46 +08:00
补充一下 mcrypt_encrypt 和 mcrypt_generic 的实现,结果都是一样的。。
public static function encrypt($input, $key) {
$key = hash('md5', $key, true);
$iv = '0000';
$size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$input = Security::pkcs5_pad($input, $size);
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $input, MCRYPT_MODE_CBC, $iv);
// output wd/OTHoIXwgHGDHcj8OTgg==
echo base64_encode($encrypted);
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($td, $key, $iv);
$data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$data = base64_encode($data);
// output wd/OTHoIXwgHGDHcj8OTgg==
private static function pkcs5_pad ($text, $blocksize) {
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
6 回复 &| &直到
09:03:45 +08:00
& & 14:16:03 +08:00
php 版 iv 的 '0' 其实是 0x30 吧. 不会写字符串吗?
& & 14:24:17 +08:00
@ 没看懂你的意思。。
& & 14:52:26 +08:00
$iv = str_repeat( chr( 0 ), 16 );
一楼已经说得很明白了 ... 我补一句 ... 这是个空白 IV ... 意思是使用 CBC 但不使用初始化向量 ...
这么做就把 CBC 的安全级降到和 ECB 一样了 ... 所以你在程序里直接使用 ECB 加密是正确的 ...
& & 14:56:41 +08:00
@ 你需要理解全是 0 的字符串和全是 0 的 Byte 数组的区别。。。
& & 14:58:02 +08:00
@ 懂了。。。
$iv = '0000';
我是找网上的例子,他们还特意注释
``` // iv same as java ````, 我一直以为 16 个 0 就相当于 Java 那段 new IvParameterSpec(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
& & 09:03:45 +08:00
function AES_PKCS5_ENCRYPT($text, $key)
$alg = MCRYPT_RIJNDAEL_128;
$mode = MCRYPT_MODE_ECB;
$iv_size = mcrypt_get_iv_size($alg, $mode);
$block_size = mcrypt_get_block_size($alg, $mode);
$iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM);
$this-&iv = $
$input = $this-&pkcs5_pad($text, $block_size);
$crypttext = mcrypt_encrypt($alg, $key, $input, $mode, $iv);
return base64_encode($crypttext);
function AES_PKCS5_DECRYPT($text, $key)
$alg = MCRYPT_RIJNDAEL_128;
$mode = MCRYPT_MODE_ECB;
$text = base64_decode($text);
$decrypted = mcrypt_decrypt($alg, $key, $text, $mode, $this-&iv);
$decrypted = $this-&pkcs5_unpad($decrypted);
function pkcs5_pad($text, $blocksize)
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
function pkcs5_unpad($text)
$pad = ord($text{strlen($text) - 1});
if ($pad & strlen($text))
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad)
return substr($text, 0, -1 * $pad);
& · & 2434 人在线 & 最高记录 3541 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.0 · 54ms · UTC 06:46 · PVG 14:46 · LAX 23:46 · JFK 02:46? Do have faith in what you're doing.posts - 54,&
comments - 11,&
trackbacks - 0
package ***;
import javax.crypto.C
import javax.crypto.spec.IvParameterS
import javax.crypto.spec.SecretKeyS
import sun.misc.BASE64D
import sun.misc.BASE64E
* AES 是一种可逆加密算法,对用户的敏感信息加密处理
* 对原始数据进行AES加密后,在进行Base64编码转化;
public class AesCBC {
* 加密用的Key 可以用26个字母和数字组成
* 此处使用AES-128-CBC加密模式,key需要为16位。
private static String sKey="3456";
private static String ivParameter="3456";
private static AesCBC instance=null;
//private static
private AesCBC(){
public static AesCBC getInstance(){
if (instance==null)
instance= new AesCBC();
public String encrypt(String sSrc, String encodingFormat, String sKey, String ivParameter) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] raw = sKey.getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());//使用CBC模式,需要一个向量iv,可增加加密算法的强度
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(sSrc.getBytes(encodingFormat));
return new BASE64Encoder().encode(encrypted);//此处使用BASE64做转码。
public String decrypt(String sSrc, String encodingFormat, String sKey, String ivParameter) throws Exception {
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);
byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);//先用base64解密
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original,encodingFormat);
return originalS
} catch (Exception ex) {
return null;
public static void main(String[] args) throws Exception {
// 需要加密的字串
String cSrc = "123456";
System.out.println("加密前的字串是:"+cSrc);
String enString = AesCBC.getInstance().encrypt(cSrc,"utf-8",sKey,ivParameter);
System.out.println("加密后的字串是:"+ enString);
System.out.println("1jdzWuniG6UMtoa3T6uNLA==".equals(enString));
String DeString = AesCBC.getInstance().decrypt(enString,"utf-8",sKey,ivParameter);
System.out.println("解密后的字串是:" + DeString);
阅读(...) 评论()

我要回帖

更多关于 java tcp怎么改为utf8 的文章

 

随机推荐