Wann ist für die Verschlüsselung eine Auffüllung erforderlich?

Ich habe hier eine Frage gestellt Warum gibt die AES Java-Entschlüsselung zusätzliche Zeichen zurück? über zusätzliche Zeichen beim Entschlüsseln der verschlüsselten Daten. Dank eines Kommentars von Benutzer "Ebbe M. Pedersen" verstehe ich jetzt, dass das Problem nicht denselben Auffüllmechanismus sowohl im PHP- als auch im Android-Java-Code verwendet. Also habe ich den Java-Code in @ geände

Java Code
 public class encryption {

    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 encryption()
    {
        ivspec = new IvParameterSpec(iv.getBytes());

        keyspec = new SecretKeySpec(SecretKey.getBytes(), "AES");

        try
        {
            cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");//"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;
    }
}

Dann habe ich das gleiche @ hinzugefüPKCS5padding funktioniert zu meinem PHPmcrypt class:

PHP mcrypt class
class MCrypt
{
    private $iv = 'fedcba9876543210'; #Same as in JAVA
    private $key = '0123456789abcdef'; #Same as in JAVA


function MCrypt()
{
}

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;
}

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)) return false;
    if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
    return substr($text, 0, -1 * $pad);
}}

Jetz das aktuelle Problem ist Senden / EmpfangenUTF-8 Zeichen, nicht wie man @ dekodiert / kodieUTF-8 Zeichen. Wenn ich arabische / persische Wörter sende, die zum Beispiel mehr als 3 oder weniger als 3 Zeichen enthalten, wird nichts zurückgegeben. Zum Beispiel: Wenn ich das Wort "خوب" sende (das genau 3 Zeichen hat), erhalte ich "خوب", was korrekt ist; aber wenn ich مچکرم sende (was 5 Zeichen hat) bekomme ich nichts.

Ich habe festgestellt, dass das Problem darin besteht, dass ich die Unpadding-Funktion nach dem Entschlüsseln der Daten in meinem PHP-Code nicht verwendet habe. Deshalb habe ich Folgendes behoben:

PHP code
<?php
$data =file_get_contents('php://input');
$block_size=mcrypt_get_block_size("rijndael-128",'cbc');
require_once "encryption.php";
$etool=new MCrypt();
$data =$etool->decrypt($data);
$data=$etool->pkcs5_unpad($data);//  <------ using unpad function
$data =json_decode($data, true);



$data=$data["request"];
$etool=new MCrypt();
$data=$etool->pkcs5_pad($data,$block_size);
$data=$etool->encrypt($data);
$array=array('data'=>$data);
echo  json_encode($array);
Und hier ist der Java-Code, um es zu bekommen
JSONObject j=new JSONObject(sb.toString());//sb is string builder
result=j.get("data").toString();
result= new String(etool.decrypt( result ),"UTF-8");
result = new String(result.getBytes("ISO-8859-1"));
Log.d("success remote ",result);

Jetzt ist das Problem umgekehrt !! Ich kann Wörter mit mehr als oder weniger als 3 persischen / arabischen Zeichen erhalten, aber keine Wörter mitgena 3 Zeichen.

Ich denke, ich sollte überprüfen, ob "Unpadding erforderlich" ist. aber wie wenn ja?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage