为什么AES解密java的回报多余的字符? [英] why AES java decryption return extra characters?
问题描述
请原谅我的英语很差。
我使用mcrypt的,我把它从这里的mcrypt的PHP和Java 。在我的Android应用程序,我需要PHP和Java安全通信,所以我得到上述AES。
问题是,当PHP发送加密数据,Java可以解密,但一些额外的字符都包括在内。
Excuse me for bad English. i use mcrypt which i get it from here MCrypt for php and java. in my android application i need php and java communicate securely so i get above mentioned AES. the problem is when php sends encrypted data, java can decrypt it but some extra characters are included.
JAVA code
JAVA Code
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class MCrypt {
private String iv = "fedcba9876543210";//Dummy iv (CHANGE IT!)
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
private String SecretKey = "0123456789abcdef";//Dummy secretKey (CHANGE IT!)
public MCrypt()
{
ivspec = new IvParameterSpec(iv.getBytes());
keyspec = new SecretKeySpec(SecretKey.getBytes(), "AES");
try {
cipher = Cipher.getInstance("AES/CBC/NoPadding");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public byte[] encrypt(String text) throws Exception
{
if(text == null || text.length() == 0)
throw new Exception("Empty string");
byte[] encrypted = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(padString(text).getBytes());
} catch (Exception e)
{
throw new Exception("[encrypt] " + e.getMessage());
}
return encrypted;
}
public byte[] decrypt(String code) throws Exception
{
if(code == null || code.length() == 0)
throw new Exception("Empty string");
byte[] decrypted = null;
try {
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
} catch (Exception e)
{
throw new Exception("[decrypt] " + e.getMessage());
}
return decrypted;
}
public static String bytesToHex(byte[] data)
{
if (data==null)
{
return null;
}
int len = data.length;
String str = "";
for (int i=0; i<len; i++) {
if ((data[i]&0xFF)<16)
str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF);
else
str = str + java.lang.Integer.toHexString(data[i]&0xFF);
}
return str;
}
public static byte[] hexToBytes(String str) {
if (str==null) {
return null;
} else if (str.length() < 2) {
return null;
} else {
int len = str.length() / 2;
byte[] buffer = new byte[len];
for (int i=0; i<len; i++) {
buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
}
return buffer;
}
}
private static String padString(String source)
{
char paddingChar = ' ';
int size = 16;
int x = source.length() % size;
int padLength = size - x;
for (int i = 0; i < padLength; i++)
{
source += paddingChar;
}
return source;
}
}
在PHP code
the PHP code
<?php
class MCrypt
{
private $iv = 'fedcba9876543210'; #Same as in JAVA
private $key = '0123456789abcdef'; #Same as in JAVA
function __construct()
{
}
function encrypt($str) {
//$key = $this->hex2bin($key);
$iv = $this->iv;
$td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv);
mcrypt_generic_init($td, $this->key, $iv);
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return bin2hex($encrypted);
}
function decrypt($code) {
//$key = $this->hex2bin($key);
$code = $this->hex2bin($code);
$iv = $this->iv;
$td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv);
mcrypt_generic_init($td, $this->key, $iv);
$decrypted = mdecrypt_generic($td, $code);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return utf8_encode(trim($decrypted));
}
protected function hex2bin($hexdata) {
$bindata = '';
for ($i = 0; $i < strlen($hexdata); $i += 2) {
$bindata .= chr(hexdec(substr($hexdata, $i, 2)));
}
return $bindata;
}
}
这样的场景就是Java发送JSON格式的数据(简单文本)到PHP,PHP提取数据,对其进行加密,最后回声它以JSON格式
so the scenario is java send data (simple text) in JSON format to PHP , php extract the data , encrypt it and finally echo it in JSON format
PHP电话:
<?php
$data =json_decode(file_get_contents('php://input'), true);
$data=$data["request"];
require_once "encryption.php";
$etool=new MCrypt();
$data=$etool->encrypt($data);
$array=array('data'=>$data);
echo json_encode($array);
JAVA code:
JAVA code:
//sb is StringBuilder
JSONObject j=new JSONObject(sb.toString());
encryption etool=new encryption();
result=j.get("data").toString();
result= new String(etool.decrypt( result ));
Log.d("success remote ",result );
结果是:
例如
如果我用波斯语/阿拉伯语中它变得更糟
and if i use Farsi/Arabic word it get worse
像这个 - >درود
like this-> درود����������������
此外,我检查了其他的问题,但我无法得到答案。
in addition, i checked other questions but i could not get the answer.
<一个href=\"http://stackoverflow.com/questions/29029410/aes-encryption-got-extra-trash-characters-in-decrypted-file\">AES加密,以解密文件和结果得到了额外的垃圾字符
<一href=\"http://stackoverflow.com/questions/16895540/php-mcrypt-encrypt-decrypt-returns-invisible-strange-characters\">PHP mcrypt的加密/解密的回报无形奇怪的字符?
AES encryption, got extra trash characters in decrypted file and
PHP MCRYPT encrypt/decrypt returns invisible strange characters?
感谢您提前!
推荐答案
AES 加密以16字节的块。如果输入不是16字节的整数倍,需要填充方案。由于您没有指定任何填充选项的mcrypt ,它使用的零填充的。
AES encrypt in blocks of 16 bytes. If your input ain't a multiple of 16 bytes, a padding scheme is needed. As you have not specified any padding option for Mcrypt, it uses "zero padding".
在您的的Java code您指定的NoPadding的,当你实例化你的密码:
In your Java code you specify "NoPadding" when you instantiate your Cipher:
cipher = Cipher.getInstance("AES/CBC/NoPadding");
所以的Java 被考虑的 PHP 是加密数据的一部分。完成填充
So Java considers the padding done by php to be part of the encrypted data.
您只需要确保您的 PHP 和的Java code使用相同的填充方案。
You just need to ensure that your php and Java code uses the same padding scheme.
这篇关于为什么AES解密java的回报多余的字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!