Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中使用AES-128加密文件,并在Android中解密_Php_Android_Encryption_Aes - Fatal编程技术网

在PHP中使用AES-128加密文件,并在Android中解密

在PHP中使用AES-128加密文件,并在Android中解密,php,android,encryption,aes,Php,Android,Encryption,Aes,我需要在PHP中使用AES-128加密一个文件,并在Android中解密它 我正在使用以下代码。我已经使用PHP代码成功地对其进行了加密和解密,但我需要从我的应用程序中使用Android对其进行解密 PHP代码: $key= "asdfghjklzxccvbn"; $in_filename = $_FILES["fileToUpload"]["tmp_name"]; $aes_filename =$target_dir."encry_".$_FILES["fileToUpload"]["n

我需要在PHP中使用AES-128加密一个文件,并在Android中解密它

我正在使用以下代码。我已经使用PHP代码成功地对其进行了加密和解密,但我需要从我的应用程序中使用Android对其进行解密

PHP代码:

$key= "asdfghjklzxccvbn";   
$in_filename = $_FILES["fileToUpload"]["tmp_name"];
$aes_filename =$target_dir."encry_".$_FILES["fileToUpload"]["name"];
$decry_filename =$target_dir."decry_".$_FILES["fileToUpload"]["name"];

//encrypt file
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = '1234567890123456';

$fin = fopen($in_filename, "rb");
$fcrypt = fopen($aes_filename, 'wb');
fwrite($fcrypt, $iv);
$opts = array('iv'=>$iv, 'key'=>$key, 'mode'=>'cbc');
stream_filter_append($fcrypt, 'mcrypt.rijndael-128', STREAM_FILTER_WRITE,     $opts);
while (!feof($fin))
{
    fwrite($fcrypt, fread($fin, 8192));
}
fclose($fcrypt);
fclose($fin);
用于解密加密文件的我的Android代码:

 // encripted file stored in android device for decrypt
 String uri= Environment.getExternalStorageDirectory().toString();
 uri=uri+"/encry_file.mp4";
 File file = new File(uri.toString());
 FileInputStream fis = new FileInputStream(file);
 spec =getIV();

 FileOutputStream fos = new FileOutputStream(Environment.getExternalStorageDirectory().toString() + "/decrypted.mp4");
 SecretKeySpec sks = new SecretKeySpec("asdfghjklzxccvbn".getBytes(),
          "AES");
 Cipher cipher = Cipher.getInstance("AES");
 cipher.init(Cipher.DECRYPT_MODE, sks, spec);
 CipherInputStream cis = new CipherInputStream(fis, cipher);

 int b;
 byte[] d = new byte[8192];
 while ((b = cis.read(d)) != -1) {
    fos.write(d, 0, b);
 }
 fos.flush();
 fos.close();
 cis.close();
获取iv函数

public AlgorithmParameterSpec getIV() {
    byte[] iv = { 1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6 };
    IvParameterSpec ivParameterSpec;
    ivParameterSpec = new IvParameterSpec(iv);

    return ivParameterSpec;
}

android代码将生成一个文件,但它不可读。请检查我的代码是否正确,或者是否有任何问题。请帮我解决它

模式和填充不匹配。在PHP中使用AES/CBC/ZeroPadding(Java表示法),但在Java中使用的是
Cipher.getInstance(“AES”)
,它(可能)默认为
Cipher.getInstance(“AES/ECB/PKCS5Padding”)
。始终使用完全限定的密码描述:

Cipher cipher = Cipher.getInstance("AES/CBC/ZeroPadding", "BC");
(这并不能解决问题。)

您没有使用相同的IV。字符“1”和字节1不是一回事,因为“1”实际上是字节49

byte[] iv = { 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54 };
由于BouncyCastles/SpongyCastles
ZeroPadding
与mcrypt的ZeroPadding不完全相同,因此应该使用
Cipher Cipher=Cipher.getInstance(“AES/CBC/NoPadding”)
以解析解密的最后16个字节,并删除尾随的0x00字节

在您的案例中,有一种方法可以做到这一点:

int b;
byte[] d = new byte[8192];
byte[] p = null;
int holdOff;
while ((b = cis.read(d)) != -1) {
    holdOff = Math.max(b - cipher.getBlockSize(), 0);
    if (p != null) {
        fos.write(p, 0, p.length);
        Arrays.fill(p, 0);
    }
    if (p == null) {
        p = new byte[cipher.getBlockSize()];
    }
    System.arraycopy(d, holdOff, p, 0, p.length);

    fos.write(d, 0, holdOff);
}

// here p contains the end of the plaintext followed by padding bytes
// remove padding:
int i = cipher.getBlockSize() - 1;
while(i >= 0 && p[i] == 0) {
    i--;
}
// write remaining bytes
fos.write(Arrays.copyOf(p, i+1), 0, i+1);

fos.flush();
fos.close();
cis.close();
我们的想法是,不要将最后16个字节写入文件,而是单独处理它们,因为解密文件的最后16个字节可能包含需要删除的0x00字节


其他考虑:
  • 始终为每次加密随机生成IV。这不一定是秘密,但必须是不可预测的。您可以将其与密文一起发送,例如,将其放在密文前面

  • 通过在密文上运行HMAC(加密然后MAC)对密文进行身份验证。在尝试解密之前,您需要检查接收方的MAC,看看它是否在途中被操纵


我无法理解你。请具体说明。。我对这件事还不熟悉。根据你的评论,我应该在哪里进行更改?我已经更改了我的android代码,但仍然不起作用。是否有任何错误?如果存在文件,结果文件与预期文件有何不同?长度一样吗?第一个、最后一个或所有字节是否不同?我无法使用它引发异常的“零填充”。我的加密文件是“encry_file.mp4”,它存储在设备内存中用于测试,我需要从中创建一个解密文件“decrypted.mp4”。您可能需要指定“noppadding”而不是“ZeroPadding”,并自己删除尾部的0x00字节,但仅仅包括海绵城堡应该更容易。