2013-10-05 16 views
15

Ho cercato di decrittografare una stringa utilizzando CBC AES-128 che è stato originariamente criptato utilizzando la crittografia AAV JAVA. In java PKCS7 viene utilizzato il padding. E ho provato a crittografare e decifrare usando un codice PHP simile. Ma sto ottenendo risultati diversi.Crittografia AES 128 in Java Decryption in PHP

codice Java mio

import java.security.MessageDigest; 
import java.security.spec.AlgorithmParameterSpec; 

import javax.crypto.Cipher; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 

import android.util.Base64; 

/** 
* @author vipin.cb , [email protected] <br> 
*   Sep 27, 2013, 5:18:34 PM <br> 
*   Package:- <b>com.veebow.util</b> <br> 
*   Project:- <b>Veebow</b> 
*   <p> 
*/ 
public class AESCrypt { 

    private final Cipher cipher; 
    private final SecretKeySpec key; 
    private AlgorithmParameterSpec spec; 
    public static final String SEED_16_CHARACTER = "U1MjU1M0FDOUZ.Qz"; 

    public AESCrypt() throws Exception { 
     // hash password with SHA-256 and crop the output to 128-bit for key 
     MessageDigest digest = MessageDigest.getInstance("SHA-256"); 
     digest.update(SEED_16_CHARACTER.getBytes("UTF-8")); 
     byte[] keyBytes = new byte[32]; 
     System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length); 

     cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); 
     key = new SecretKeySpec(keyBytes, "AES"); 
     spec = getIV(); 
    } 

    public AlgorithmParameterSpec getIV() { 
     byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; 
     IvParameterSpec ivParameterSpec; 
     ivParameterSpec = new IvParameterSpec(iv); 

     return ivParameterSpec; 
    } 

    public String encrypt(String plainText) throws Exception { 
     cipher.init(Cipher.ENCRYPT_MODE, key, spec); 
     byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8")); 
     String encryptedText = new String(Base64.encode(encrypted, 
       Base64.DEFAULT), "UTF-8"); 

     return encryptedText; 
    } 

    public String decrypt(String cryptedText) throws Exception { 
     cipher.init(Cipher.DECRYPT_MODE, key, spec); 
     byte[] bytes = Base64.decode(cryptedText, Base64.DEFAULT); 
     byte[] decrypted = cipher.doFinal(bytes); 
     String decryptedText = new String(decrypted, "UTF-8"); 

     return decryptedText; 
    } 

} 

E il codice PHP equivalente sto usando.

<?php 

class MCrypt { 

    private $iv = '0000000000000000'; #Same as in JAVA    
    private $key = 'U1MjU1M0FDOUZ.Qz'; #Same as in JAVA 

    function __construct() { 
     $this->key = hash('sha256', $this->key, true); 
    } 

    function encrypt($str) { 
     $iv = $this->iv; 
     $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); 
     mcrypt_generic_init($td, $this->key, $iv); 
     $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
     $pad = $block - (strlen($str) % $block); 
     $str .= str_repeat(chr($pad), $pad); 
     $encrypted = mcrypt_generic($td, $str); 
     mcrypt_generic_deinit($td); 
     mcrypt_module_close($td); 
     return base64_encode($encrypted); 
    } 

    function decrypt($code) { 
     $iv = $this->iv; 
     $td = mcrypt_module_open('rijndael-128', '', 'cbc', ''); 
     mcrypt_generic_init($td, $this->key, $iv); 
     $str = mdecrypt_generic($td, base64_decode($code)); 
     $block = mcrypt_get_block_size('rijndael-128', 'cbc'); 
     mcrypt_generic_deinit($td); 
     mcrypt_module_close($td); 
     return $str; 
     //return $this->strippadding($str);    
    } 

    /* 
     For PKCS7 padding 
    */ 
    private function addpadding($string, $blocksize = 16) { 
     $len = strlen($string); 
     $pad = $blocksize - ($len % $blocksize); 
     $string .= str_repeat(chr($pad), $pad); 
     return $string; 
    } 

    private function strippadding($string) { 
     $slast = ord(substr($string, -1)); 
     $slastc = chr($slast); 
     $pcheck = substr($string, -$slast); 
     if (preg_match("/$slastc{" . $slast . "}/", $string)) { 
      $string = substr($string, 0, strlen($string) - $slast); 
      return $string; 
     } else { 
      return false; 
     } 
    } 

} 

$encryption = new MCrypt(); 
echo $encryption->encrypt('123456') . "<br/>"; 
echo $encryption->decrypt('tpyxISJ83dqEs3uw8bN/+w=='); 

In Java
Testo normale = 123456
testo cifrato = tpyxISJ83dqEs3uw8bN/+ w ==

In PHP

Testo normale = 123456
testo cifrato = == IErqfTCktrnmWndOpq3pnQ

Quando ho provato a decrittare il testo crittografato di Java "tpyxISJ83dqEs3uw8bN/+ w ==" usando la decodifica PHP I am ge tting un array vuoto se ho rimosso il padding. Senza rimuovere il padding sto ricevendo ":::::::::"

Penso che ci sia un errore con i byte IV utilizzati in PHP e Java Qualcuno può aiutarmi su questo. Ho provato molte combinazioni. Ancora nessun risultato. Sono molto nuovo ai concetti di Java.

------ Soluzione -------

ho modificato la mia classe php secondo le osservazioni fornite dal owlstead. potrebbe esserci c'è un modo migliore. Sto postando qui in modo che qualcuno possa trovarlo utile in futuro e i tuoi commenti sono benvenuti per ulteriori miglioramenti.

<?php 

class MCrypt { 

    private $hex_iv = '00000000000000000000000000000000'; # converted Java byte code in to HEX and placed it here    
    private $key = 'U1MjU1M0FDOUZ.Qz'; #Same as in JAVA 

    function __construct() { 
     $this->key = hash('sha256', $this->key, true); 
     //echo $this->key.'<br/>'; 
    } 

    function encrypt($str) {  
     $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); 
     mcrypt_generic_init($td, $this->key, $this->hexToStr($this->hex_iv)); 
     $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
     $pad = $block - (strlen($str) % $block); 
     $str .= str_repeat(chr($pad), $pad); 
     $encrypted = mcrypt_generic($td, $str); 
     mcrypt_generic_deinit($td); 
     mcrypt_module_close($td);   
     return base64_encode($encrypted); 
    } 

    function decrypt($code) {   
     $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); 
     mcrypt_generic_init($td, $this->key, $this->hexToStr($this->hex_iv)); 
     $str = mdecrypt_generic($td, base64_decode($code)); 
     $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
     mcrypt_generic_deinit($td); 
     mcrypt_module_close($td);   
     return $this->strippadding($str);    
    } 

    /* 
     For PKCS7 padding 
    */ 

    private function addpadding($string, $blocksize = 16) { 
     $len = strlen($string); 
     $pad = $blocksize - ($len % $blocksize); 
     $string .= str_repeat(chr($pad), $pad); 
     return $string; 
    } 

    private function strippadding($string) { 
     $slast = ord(substr($string, -1)); 
     $slastc = chr($slast); 
     $pcheck = substr($string, -$slast); 
     if (preg_match("/$slastc{" . $slast . "}/", $string)) { 
      $string = substr($string, 0, strlen($string) - $slast); 
      return $string; 
     } else { 
      return false; 
     } 
    } 
function hexToStr($hex) 
{ 
    $string=''; 
    for ($i=0; $i < strlen($hex)-1; $i+=2) 
    { 
     $string .= chr(hexdec($hex[$i].$hex[$i+1])); 
    } 
    return $string; 
} 
} 

$encryption = new MCrypt(); 
echo $encryption->encrypt('123456') . "<br/>"; 
echo $encryption->decrypt('tpyxISJ83dqEs3uw8bN/+w=='); 
+0

GRAZIE. Questo e 'esattamente quello che stavo cercando. corretto un errore di battitura nella mia chiave e presto magico! – ssdscott

+0

@ssdscott sono contento che ti abbia aiutato anche dopo aver postato 2 anni indietro :) – shanavascet

risposta

9

vostro IV è diverso, un byte con valore zero è diverso da un personaggio '0', che si tradurrebbe in un byte con un valore 30 in esadecimale o 48 in decimali (se si presume ASCII o codifica UTF-8).

+0

quale dovrebbe essere il IV .. ho dato 16 spazi per IV senza fortuna. Ho provato a convertire byte iv in string in java e ho ottenuto stringhe vuote con lunghezza 16. Ho provato a criptare in php usandolo senza fortuna. – shanavascet

+2

Confrontare i valori dei byte dell'IV su entrambe le piattaforme. Ricorda che l'input e l'output delle cifre simmetriche è in byte e che l'ordine dei byte è stato predefinito per le cifre. Dovresti sempre ottenere lo stesso risultato irrilevante della piattaforma. Quindi assicurati che i valori inseriti negli algoritmi siano identici su entrambe le piattaforme. Il modo migliore per farlo è stampare i valori di input in esadecimali subito prima di eseguire l'operazione di crittografia. Attenzione ai problemi di codifica/decodifica (carattere)! Se possibile, testare l'input/output dell'algoritmo stesso usando array * di byte identici *. –

+0

grazie mille gufi .. ho seguito i passi che hai citato .. grazie per la tua pazienza di rispondere alla mia domanda e per i commenti qui ... ti amo. – shanavascet

Problemi correlati