使用AES加密和解密音频/视频文件(128)

时间:2013-04-20 10:01:45

标签: java sockets aes encryption

我正在编写一个程序,将音频/视频文件发送到服务器,在那里数据被加密并发送回套接字上的客户端。在客户端部分,数据被提取并被解密并存储到另一个文件中。数据也被加密和解密,但解密的文件无法正常播放。

有人可以帮忙吗?我的代码如下

服务器

    public class Ser_enc 
    {
    private static int packet_count;
    private static int packet_size=1024;
    public static void main(String args[]) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException
    {
    System.out.println("Hi iam server");
    ServerSocket ss=new ServerSocket(2001);
    Socket s=ss.accept();

    BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream()));//sockin

    OutputStream pw= s.getOutputStream();


    String filename=in.readLine();
    System.out.println("The file requested is " +filename);

    String loc="F://files//source_files//"+filename;

    File file=new File(loc);

    if(file.exists())
    System.out.println("File found");

    File to_b_encf =new File("F:/files/source_files//encryped.mp3");

    if(!to_b_encf.exists())
    to_b_encf.createNewFile();

    System.out.println("encrypting");

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

    KeyGenerator kgen = KeyGenerator.getInstance("AES");

    SecretKey skey = kgen.generateKey();//initiate key

    encipher.init(Cipher.ENCRYPT_MODE, skey);

    FileInputStream fsrc=new FileInputStream(loc);

    FileOutputStream encfile=new FileOutputStream(to_b_encf);

    CipherInputStream cis = new CipherInputStream(fsrc, encipher);

    int read;
    while((read=cis.read())!=-1)
    {
      encfile.write(read);
      encfile.flush();
    }

     BufferedInputStream fsrcread=new BufferedInputStream(new   FileInputStream(to_b_encf));

    packet_count = (int) Math.ceil((to_b_encf.length()/packet_size));
    System.out.println("The number of packets to send is :" +packet_count);
    for(int i=0;i<=packet_count;i++)
    {
    byte[] packet=new byte[packet_size];

    fsrcread.read(packet, 0, packet_size);

    int per=(int)((i*100)/(packet_count));

    System.out.println("Transfer " +per +"% done");

    pw.write(packet);
    pw.flush();

    }
    s.close();
   pw.close();
   cis.close();
   encfile.close();
   }
   }

客户端:

public class Cli_dec 
{
    private static Socket s;
     private static int read;
    public static void main(String args[]) throws UnknownHostException, IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException
    {

        s=new Socket("127.0.0.1",2001);

        PrintWriter out=new PrintWriter(s.getOutputStream());

        String fname=JOptionPane.showInputDialog(null);

        out.write(fname+"\n");
        out.flush();

        int count;
        byte[] buf=new byte[100000];
        System.out.println("Receiving packets");
        File f=new File("F:/files/source_files//decryped.mp3");
        FileOutputStream to_b_decf=new FileOutputStream(f);
        BufferedOutputStream bos=new BufferedOutputStream(to_b_decf);
        InputStream in1=s.getInputStream();

        while((count=in1.read(buf))>0)
        {
        bos.write(buf, 0,count);
        bos.flush();
        }

        File destfile =new File("F:/files/source_files//original.mp3");

        if(!destfile.exists())
        destfile.createNewFile();

        Cipher decipher = Cipher.getInstance("AES");//initiate a cipher for decryption
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecretKey skey = kgen.generateKey();//initiate key
        decipher.init(Cipher.DECRYPT_MODE, skey);//decrypt the file 

        FileInputStream decf=new FileInputStream(f);

        System.out.println("decrypting");

        CipherInputStream c_decf=new CipherInputStream(decf,decipher);

        FileOutputStream destf=new FileOutputStream(destfile);

        CipherOutputStream cout=new CipherOutputStream(destf,decipher);


        while((read=c_decf.read())!=-1)
        {
         cout.write(read);
         cout.flush();
         }
        c_decf.close();
        destf.close();
        cout.close();
        decf.close();
        s.close();
}

}

2 个答案:

答案 0 :(得分:1)

您在客户端中使用kgen.generateKey(),它会生成一个随机密钥 - 您需要为服务器和客户端使用相同的密钥,否则您将获得乱码。

accepted answer to this question有一些可以使用的良好加密代码 - 使用KeySpec spec = new PBEKeySpec(password, salt, 64, 128);来减少迭代次数并使用128位加密而不是256位加密。此代码还使用密码块链接而不是电子密码本,这更加安全(see this Wikipedia article for an explanation of cipher modes)。服务器和客户端都需要使用相同的密钥生成代码,以便它们的密钥匹配;除了使用相同的密钥之外,加密器和解密器还需要使用相同的初始化向量(IV),但这不是秘密的(可以用明文传输)。

答案 1 :(得分:1)

我正在开发类似你问的应用程序,你的代码帮助我很好。

在客户端模块中你做了双重解密...我的代码看起来像这样

CipherInputStream c_decf = new CipherInputStream(decf, decipher);

    FileOutputStream destf = new FileOutputStream(destfile);

    //CipherOutputStream cout = new CipherOutputStream(destf, decipher);


    while ((read = c_decf.read()) != -1) {
        destf.write(read);
        destf.flush();
    }
    c_decf.close();
    destf.close();
   // cout.close();
    decf.close();

只需删除它,然后将密钥生成为How do i decrypt a file in Android with AES?。代码有效。

感谢您发布此问题。