Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.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
Java AES解密的3gp文件似乎已损坏_Java_Android_Encryption_Aes - Fatal编程技术网

Java AES解密的3gp文件似乎已损坏

Java AES解密的3gp文件似乎已损坏,java,android,encryption,aes,Java,Android,Encryption,Aes,我在使用AES算法对文件进行编码和解码时遇到问题。我正在用android录制音频并加密录制的文件,通过webservice发送到另一个应用程序和另一个应用程序,文件被解密。密钥也会正常发送和到达 问题是,要用密钥解密文件,当用android player和VLC Media player打开文件时,文件似乎已损坏 回想一下,未加密的文件到达另一方时没有问题,密钥也没有问题 密钥是为记录的每个文件随机生成的32个字符的字符串。下面是加密和解密文件的类 格式为.3 gp。我使用的android仅作为

我在使用AES算法对文件进行编码和解码时遇到问题。我正在用android录制音频并加密录制的文件,通过webservice发送到另一个应用程序和另一个应用程序,文件被解密。密钥也会正常发送和到达

问题是,要用密钥解密文件,当用android player和VLC Media player打开文件时,文件似乎已损坏

回想一下,未加密的文件到达另一方时没有问题,密钥也没有问题

密钥是为记录的每个文件随机生成的32个字符的字符串。下面是加密和解密文件的类

格式为.3 gp。我使用的android仅作为mp4和3gp使用

在这种情况下该怎么办

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import android.content.Context;

public class AES extends Cripto {

public static void encrypt(Context c, String nomeArquivo)
        throws IOException, NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException {



    String key = GenerateKey(); //key 32 character randomly generated


    String pathFilePure = new _Path().getPathFilePure();
    String pathFileCripted = new _Path().getPathFileCripto();

    FileInputStream fis = new FileInputStream(pathFilePure + "/"
            + nomeArquivo);
    FileOutputStream fos = new FileOutputStream(pathFileCripted + "/"
            + nomeArquivo);


    SecretKeySpec sks = new SecretKeySpec(key.getBytes(), "AES");

    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, sks);

    CipherOutputStream cos = new CipherOutputStream(fos, cipher);

    int b;
    byte[] d = new byte[8];

    while ((b = fis.read(d)) != -1) {
        cos.write(d, 0, b);
    }

    cos.flush();
    cos.close();
    fis.close();        
}

public static void decrypt(Context c, String fileName, String key)
        throws IOException, NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException {
    FileInputStream fis = new FileInputStream(
            new _Path().getPathFileDownload() + "/" + fileName);

    FileOutputStream fos = new FileOutputStream(
            new _Path().getPathFileDescripto() + "/" + fileName);
    SecretKeySpec sks = new SecretKeySpec(key.getBytes(), "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, sks);
    CipherInputStream cis = new CipherInputStream(fis, cipher);
    int b;
    byte[] d = new byte[8];

    while ((b = cis.read(d)) != -1) {
        fos.write(d, 0, b);
    }

    fos.flush();
    fos.close();
    cis.close();
}

}

没有32个字符的AES密钥。AES密钥是256位或AES-256的32字节。如果您创建随机字节(您应该这样做),那么不是每个字节都代表一个可打印字符。因此,如果将字节“解码”为
字符串
实例(例如,使用
新字符串(字节)
),则可能会丢失数据


如果您需要字符串,请查看我的答案。请注意,您不应使用ECB模式加密,如果您指定
“AES”,这是默认设置
作为
密码的算法
。也不要使用默认值。

我一直在研究并设法解决下面的类的问题,该类现在可以工作,即加密和解密

 package com.infovale.cripto;

 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.math.BigInteger;
 import java.util.Arrays;

 import javax.crypto.Cipher;
 import javax.crypto.CipherInputStream;
 import javax.crypto.CipherOutputStream;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;

 import android.content.Context;

 public class AES extends Cripto {

public static String encrypt(Context c, String nomeArquivo) {
    String caminhoArquivoPuro = new _Path().getPathFilePure() + "/"
            + nomeArquivo;
    String caminhoArquivoCriptografado = new _Path().getPathFileCripto()
            + "/" + nomeArquivo;

    String key = null;
    ;

    try {
        FileInputStream fis = new FileInputStream(new File(
                caminhoArquivoPuro));
        File outfile = new File(caminhoArquivoCriptografado);

        int read;
        if (!outfile.exists())
            outfile.createNewFile();

        FileOutputStream fos = new FileOutputStream(outfile);
        FileInputStream encfis = new FileInputStream(outfile);

        Cipher encipher = Cipher.getInstance("AES");

        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecretKey skey = kgen.generateKey();
        encipher.init(Cipher.ENCRYPT_MODE, skey);
        CipherInputStream cis = new CipherInputStream(fis, encipher);

        key = bytesToString(skey.getEncoded());

        byte[] b = stringToBytes(key);

        while ((read = cis.read()) != -1) {
            fos.write((char) read);
            fos.flush();
        }
        fos.close();

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        entityFiles file = new entityFiles();

        file.setCaminhoArquivoPuro(caminhoArquivoPuro);
        file.setCaminhoArquivoCriptografado(caminhoArquivoCriptografado);
        file.setKeyArquivo(key);
        file.setNomeArquivo(nomeArquivo);

        ArquivoDataSource datasource = new ArquivoDataSource(c);

        datasource.open();

        file = datasource.createRegistro(file);

        datasource.close();
    }

    return key;
}

public static void decrypt(Context c, String nomeArquivo, String key) {

    String caminhoArquivoPuro = new _Path().getPathFileCripto() + "/"
            + nomeArquivo;
    String caminhoArquivoCriptografado = new _Path().getPathFileDescripto()
            + "/" + nomeArquivo;

    try {
        FileInputStream fis = new FileInputStream(new File(
                caminhoArquivoPuro));
        File outfile = new File(caminhoArquivoPuro);

        int read;
        if (!outfile.exists()) {
            outfile.createNewFile();
        }

        File decfile = new File(caminhoArquivoCriptografado);

        if (!decfile.exists()) {
            decfile.createNewFile();
        }

        FileInputStream encfis = new FileInputStream(outfile);
        FileOutputStream decfos = new FileOutputStream(decfile);

        Cipher decipher = Cipher.getInstance("AES");            



        SecretKey originalKey = new SecretKeySpec(stringToBytes(key), 0,
                stringToBytes(key).length, "AES");


        decipher.init(Cipher.DECRYPT_MODE, originalKey);
        CipherOutputStream cos = new CipherOutputStream(decfos, decipher);

        while ((read = encfis.read()) != -1) {
            cos.write(read);
            cos.flush();
        }
        cos.close();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static String bytesToString(byte[] b) {
    byte[] b2 = new byte[b.length + 1];
    b2[0] = 1;
    System.arraycopy(b, 0, b2, 1, b.length);
    return new BigInteger(b2).toString(36);
}

public static byte[] stringToBytes(String s) {
    byte[] b2 = new BigInteger(s, 36).toByteArray();
    return Arrays.copyOfRange(b2, 1, b2.length);
}

 }
使用字符串worked=),我很难安装tie来加密文件。如果(!outfile.exists())outfile.createNewFile(),则不需要
。您只是在重复
新建FileOutputStream()
也会做的工作,但它仍然会这样做,此外,它现在必须删除您创建的文件,因此您实际上浪费了更多的时间。