Encriptación AES 128 en Java Descifrado en PHP
He estado tratando de descifrar una cadena usando AES-128 CBC que originalmente fue encriptado usando el cifrado AES de JAVA. En java PKCS7 se utiliza el relleno. Y he intentado cifrar y descifrar usando código PHP similar. Pero estoy obteniendo resultados diferentes.
Mi código Java
- Escritorio remoto basado en web para conectarse a android
- ¿Cómo administrar sesión para un usuario conectado desde una aplicación móvil en PHP?
- Valor siempre devuelve 0 donde debe devolver el número de fila insertada
- ¿Cómo identificar imágenes similares a pesar de haber sido recortadas?
- Envío de datos JSON de Android a PHP y escritura a archivo de texto
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; } }
Y el código PHP equivalente que estoy 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==');
En Java
Texto llano = 123456
Texto de cifrado = tpyxISJ83dqEs3uw8bN / + w ==
En PHP
Texto llano = 123456
Texto cifrado = IErqfTCktrnmWndOpq3pnQ ==
Cuando traté de decrpt el texto encriptado de Java "tpyxISJ83dqEs3uw8bN / + w ==" usando el descifrado PHP estoy recibiendo una matriz vacía si he eliminado el relleno. Sin quitar el relleno estoy recibiendo "::::::::::"
Creo que hay algún error con los IV bytes utilizados en PHP y Java ¿Puede alguien ayudarme en esto. He intentado muchas combinaciones. Todavía no hay resultado. Soy muy nuevo en los conceptos de Java.
——Solución——-
He modificado mi clase de php de acuerdo con los comentarios dados por owlstead. Puede ser que hay una mejor manera. Estoy publicándolo aquí para que alguien pueda encontrarlo útil en el futuro y sus comentarios son bienvenidos para una mayor mejora.
<?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==');
- Android en la facturación de aplicaciones v3 con php
- Extraer datos de la clave pública de RSA
- ¿Cómo puedo comprobar la compra en la aplicación de google en php?
- ¿Cómo enviar una notificación push a más de 1000 usuarios que utilizan firebase en Android?
- Seguridad y autenticación cliente-servidor
- Detectar navegador de aplicaciones (WebView) con PHP / Javascript
- Android MediaPlayer Streaming desde un redireccionamiento PHP no funciona-out!
- El servidor GCM de Google devuelve Error no autorizado 401
Su IV es diferente, un byte con valor cero es diferente de un carácter '0'
que se traduciría en un byte con valor 30
en hexadecimales o 48 en decimales (si se supone ASCII o codificación UTF-8).
- Cómo crear el modelo de cara de usuario dinámico en android?
- Adaptador de sincronización de contactos en android