1

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

任何人都可以帮忙吗?我的代码如下

服务器:

    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();
}

}
4

2 回答 2

1

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

这个问题的公认答案有一些很好的加密代码可供您使用 - 用于KeySpec spec = new PBEKeySpec(password, salt, 64, 128);减少迭代次数并使用 128 位加密而不是 256 位加密。此代码还使用密码块链接而不是电子密码本,这更加安全(有关密码模式的说明,请参阅此 Wikipedia 文章)。服务器和客户端都需要使用相同的密钥生成代码,以便它们的密钥匹配;除了使用相同的密钥之外,加密器和解密器还需要使用相同的初始化向量 (IV),但这不是秘密(可以以明文形式传输)。

于 2013-04-20T13:30:48.513 回答
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();

只需将其删除并生成密钥,如我如何使用 AES 在 Android 中解密文件?. 代码有效。

感谢您发布这个问题。

于 2014-12-24T12:43:38.183 回答