2012-03-12 23 views
5

En mi aplicación para Android me estoy comunicando con un servicio web, los datos enviados y respondidos están encriptados con encriptación AES.Encriptación AES Java -> PHP -> Java

Lo que hago es lo siguiente. Enviaré una cadena JSON codificada AES codificada en base64 para compartir.php

Share.php descifrará esta cadena e insertará en la base de datos. Después de eso, PHP encriptará y codificará la respuesta.

Mi aplicación de Android necesita decodificar y descifrar este mensaje.

Pero el descifrado de la respuesta de PHP no va muy bien.

Esta es mi AES.java:

public class AES { 
private final String characterEncoding = "UTF-8"; 
private final String cipherTransformation = "AES/ECB/PKCS5Padding"; 
private final String aesEncryptionAlgorithm = "AES"; 

public byte[] decrypt(byte[] cipherText, byte[] key, byte [] initialVector) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException 
{ 
    Cipher cipher = Cipher.getInstance(cipherTransformation); 
    SecretKeySpec secretKeySpecy = new SecretKeySpec(key, aesEncryptionAlgorithm); 
    //IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector); 
    //cipher.init(Cipher.DECRYPT_MODE, secretKeySpecy, ivParameterSpec); 
    cipher.init(Cipher.DECRYPT_MODE, secretKeySpecy); 
    System.out.println("Do final: "+cipherText); 

    cipherText = cipher.doFinal(cipherText); 
    return cipherText; 
} 

public byte[] encrypt(byte[] plainText, byte[] key, byte [] initialVector) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException 
{ 
    Cipher cipher = Cipher.getInstance(cipherTransformation); 
    SecretKeySpec secretKeySpec = new SecretKeySpec(key, aesEncryptionAlgorithm); 
    //IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector); 
    //cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); 
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); 
    plainText = cipher.doFinal(plainText); 
    return plainText; 
} 

private byte[] getKeyBytes(String key) throws UnsupportedEncodingException{ 
    byte[] keyBytes= new byte[16]; 
    byte[] parameterKeyBytes= key.getBytes(characterEncoding); 
    System.arraycopy(parameterKeyBytes, 0, keyBytes, 0, Math.min(parameterKeyBytes.length, keyBytes.length)); 
    return keyBytes; 
} 

/// <summary> 
/// Encrypts plaintext using AES 128bit key and a Chain Block Cipher and returns a base64 encoded string 
/// </summary> 
/// <param name="plainText">Plain text to encrypt</param> 
/// <param name="key">Secret key</param> 
/// <returns>Base64 encoded string</returns> 
public String encrypt(String plainText, String key) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException{ 
    byte[] plainTextbytes = plainText.getBytes(characterEncoding); 
    byte[] keyBytes = getKeyBytes(key); 
    //return Base64.encodeToString(encrypt(plainTextbytes,keyBytes, keyBytes), Base64.DEFAULT); 
    return Base64.encodeToString(encrypt(plainTextbytes,keyBytes, new byte[0]), Base64.DEFAULT); 
} 

/// <summary> 
/// Decrypts a base64 encoded string using the given key (AES 128bit key and a Chain Block Cipher) 
/// </summary> 
/// <param name="encryptedText">Base64 Encoded String</param> 
/// <param name="key">Secret Key</param> 
/// <returns>Decrypted String</returns> 
public String decrypt(String encryptedText, String key) throws KeyException, GeneralSecurityException, GeneralSecurityException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException{ 
    byte[] cipheredBytes = Base64.decode(encryptedText, Base64.DEFAULT); 
    byte[] keyBytes = getKeyBytes(key); 
    //return new String(decrypt(cipheredBytes, keyBytes, keyBytes), characterEncoding); 
    return new String(decrypt(cipheredBytes, keyBytes, new byte[0]), characterEncoding); 
} 

}

Y este es el código para codificar en cifrar la respuesta en PHP:

function mc_encrypt($encrypt, $mc_key) { 
    $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_RAND); 
    $passcrypt = trim(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $mc_key, trim($encrypt), MCRYPT_MODE_ECB, $iv)); 
    $encode = base64_encode($passcrypt); 
    return $encode; 
} 

function mc_decrypt($decrypt, $mc_key) { 
    $decoded = base64_decode($decrypt); 
    $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_RAND); 
    $decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $mc_key, trim($decoded), MCRYPT_MODE_ECB, $iv)); 
    return $decrypted; 
} 

supongo que los ajustes de el cifrado de PHP no coincide con la configuración de la parte de Java. Puede

Estoy recibiendo el siguiente error:

03-12 13:44:09.661: W/System.err(15717): javax.crypto.BadPaddingException: pad block corrupted 
+2

¿Por qué no usar https? – kirilloid

+1

Una cosa es que los modos de relleno no coinciden, consulte http://www.php.net/manual/de/ref.mcrypt.php#69782 – Niko

Respuesta

0

le sugiero que tome un vistazo a http://phpaes.com/. Es una biblioteca de cifrado AES gratuita implementada exclusivamente en PHP; es rápido y muy simple de usar.

Por lo menos, le permite estar un paso más cerca de aislar el verdadero origen del problema.

+1

Otra cosa a tener en cuenta: 'base64 encoding' viene en muchos diferentes formas y tamaños. Cuando se trata de codificar datos binarios en base64, debe estar absolutamente seguro de que tanto el código del lado del cliente como el del lado del servidor funcionan correctamente. Sugeriría comenzar con algo más simple que los datos encriptados, probar sus instalaciones y asegurarse de tener todas las bases más básicas cubiertas. – infomaniac

-4

Puede que esta no sea la respuesta que está buscando, pero ¿hay alguna razón específica para cifrar manualmente estos datos en lugar de utilizar SSL/HTTPS?

En la mayoría de los casos, HTTPS será más fácil de implementar y más seguro que la implementación manual de un cifrado simétrico.

+0

SSL/HTTPS no reemplaza un cifrado simétrico y hay situaciones donde incluso un canal SSL/HTTPS no es confiable. –

Cuestiones relacionadas