我正在编写一个程序,将音频/视频文件发送到服务器,在那里数据被加密并发送回套接字上的客户端。在客户端部分,数据被提取并被解密并存储到另一个文件中。数据也被加密和解密,但解密的文件无法正常播放。
有人可以帮忙吗?我的代码如下
服务器
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();
}
}
答案 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?。代码有效。
感谢您发布此问题。