可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
So my problem is this: i have a password that i'm encrypting in Laravel 5.6 with AES-256-CBC and send it to an android device, problem is i can't find a way to decrypt it knowing that i found a way to extract the IV and the encrypted value and the key is available on the android device !
I'm successfully decrypting the value if i use AES-128-CBC using this code on the android device, but failing the AES-256-CBC cypher and i don't understand where the problem is ! The code :
public static String decrypt(byte[] keyValue, String ivValue, String encryptedData) throws Exception { Key key = new SecretKeySpec(keyValue, "AES"); byte[] iv = Base64.decode(ivValue.getBytes("UTF-8"), Base64.DEFAULT); byte[] decodedValue = Base64.decode(encryptedData.getBytes("UTF-8"), Base64.DEFAULT); Cipher c = Cipher.getInstance("AES/CBC/PKCS7Padding"); c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv)); byte[] decValue = c.doFinal(decodedValue); return new String(decValue); }
At what instance it's specified that this code should use AES-128 and not 256 ? and how can i change it !
Thanks in advance !
EDIT
the PHP code is as follows :
$cipher="AES-256-CBC"; $key='somerandomkeyof32byteslong'; $crypt=new Encrypter($key,$cipher); $result=$crypt->encryptString('oussama'); //i'm sending the result to the android device
回答1:
Try this one
Security.java
import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; public class Security { public static String encrypt(String input, String key){ byte[] crypted = null; try{ SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, skey); crypted = cipher.doFinal(input.getBytes()); }catch(Exception e){ System.out.println(e.toString()); } return new String(Base64.encodeBase64(crypted)); } public static String decrypt(String input, String key){ byte[] output = null; try{ SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, skey); output = cipher.doFinal(Base64.decodeBase64(input)); }catch(Exception e){ System.out.println(e.toString()); } return new String(output); } public static void main(String[] args) { String key = "1234567891234567"; String data = "example"; System.out.println(Security.decrypt(Security.encrypt(data, key), key)); System.out.println(Security.encrypt(data, key)); } }
Security.php
class Security { public static function encrypt($input, $key) { $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB); $input = Security::pkcs5_pad($input, $size); $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, ''); $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND); mcrypt_generic_init($td, $key, $iv); $data = mcrypt_generic($td, $input); mcrypt_generic_deinit($td); mcrypt_module_close($td); $data = base64_encode($data); return $data; } private static function pkcs5_pad ($text, $blocksize) { $pad = $blocksize - (strlen($text) % $blocksize); return $text . str_repeat(chr($pad), $pad); } public static function decrypt($sStr, $sKey) { $decrypted= mcrypt_decrypt( MCRYPT_RIJNDAEL_128, $sKey, base64_decode($sStr), MCRYPT_MODE_ECB ); $dec_s = strlen($decrypted); $padding = ord($decrypted[$dec_s-1]); $decrypted = substr($decrypted, 0, -$padding); return $decrypted; } }?>
Example.php
<?php include 'security.php'; $value = 'plain text'; $key = "your key"; //16 Character Key echo "Encrypt =>"."<br><br>"; echo Security::encrypt($value, $key); echo "<br><br>"."Decrypt =>"."<br><br>"; echo Security::decrypt("AES Encrypted response",$key); //echo Security::decrypt(Security::encrypt($value, $key), $key); ?>
回答2:
If you need AES
with 256 bit key length, you can do it like this:
Cipher c = Cipher.getInstance("AES_256/CBC/PKCS7Padding");
Android reference sometimes better than oracle when you want to use java classes for android. Here is reference.
But remember that is only api 26+. You can compile openssl and use it in an JNI if you need support for previous versions(and I think you need to do). or find another cryptographic library for java.