2017-04-04 27 views
0

我试图做加密,并使用DES算法进行解密。对于enryption我没有问题,并成功地将明文转换为字节数组。但是我无法将密文解密为正常的明文。我认为我的解密方法有一些问题。在这里我的编码解密DES算法方法不好填充

import java.io.ByteArrayInputStream;  
import java.io.ByteArrayOutputStream;  
import javax.crypto.Cipher;  
import javax.crypto.CipherInputStream;  
import javax.crypto.CipherOutputStream;  
import javax.crypto.spec.IvParameterSpec;  
import javax.crypto.spec.SecretKeySpec;  
import javax.xml.bind.DatatypeConverter; 

public class FileEncryption { 

    //Initial Vector 
    public static final byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };  

    //EncryptAndDecrypt String -> Input : PlainText + Return : CipherText+DecipherText 
    public static String encryptString(String src) throws Exception 
    { 
     String dst=""; 
     //Not Input! 
     if(src == null || src.length()==0) 
      return ""; 

     //Encryption Setting 
     byte[] k="Multimediaproces".getBytes(); 
     SecretKeySpec Key = new SecretKeySpec(k,"AES"); 
     IvParameterSpec ivspec = new IvParameterSpec(iv); 
     Cipher encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     encryptCipher.init(Cipher.ENCRYPT_MODE,Key,ivspec); 

     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     CipherOutputStream cout = new CipherOutputStream(baos,encryptCipher); 
     cout.write(src.getBytes()); 
     cout.flush();    //ByteOutputStream -> Write Encryption Text 
     cout.close();   
     dst = DatatypeConverter.printHexBinary(baos.toByteArray()); 
     return dst; 
    } 
    //String src -> EncryptedData 
    public static String decryptString(String src) throws Exception 
    { 
     //src value is Encrypted Value! 
     //So, src value -> Not Byte! 
     //String dst=""; 
     byte[] encryptedBytes = src.getBytes();   
     //Not Input! 
     if(src == null || src.length()==0) 
      return "";   
     //Decryption Setting 
     IvParameterSpec ivspec = new IvParameterSpec(iv); 
     byte[] k="Multimediaproces".getBytes(); 
     SecretKeySpec Key = new SecretKeySpec(k,"AES"); 
     Cipher decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     decryptCipher.init(Cipher.DECRYPT_MODE,Key,ivspec); 

     //ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     ByteArrayInputStream bais = new ByteArrayInputStream(encryptedBytes); 
     CipherInputStream cin = new CipherInputStream(bais,decryptCipher); 
     //CipherOutputStream cout = new CipherOutputStream(baos,decryptCipher); 
     //cout.write(src.getBytes()); 
     byte[] buf = new byte[1024]; 
     int read; 
     while((read=cin.read(buf))>=0) //reading encrypted data! 
     { 
      cin.read(buf,0,read);  //writing decrypted data! 
      //read = cin.read(buf); 
     } 
     // closing streams 
     //baos.write(decryptCipher.doFinal()); 
     //return baos.toString(); 
     //cin.close(); 
     return bais.toString(); 
    } 
} 

当我运行的代码 error messages

+0

不要在新的代码中使用DES,它是不是安全的,并通过AES已被取代。也不要使用静态IV,使用随机IV并将其加到解密期间使用的加密数据中。 – zaph

+0

您使用'getBytes()'但不指定编码,以便您可以获得UTF-16或UTF-8,指定编码。而是使用'getBytes(“UTF-8”)'。 – zaph

+0

那么我应该如何解决它?你能给我一些代码吗 – noobie

回答

1

在你encryptString方法,你改造字节十六进制字符串错误表示:

dst = DatatypeConverter.printHexBinary(baos.toByteArray()); 

所以,为了解密,则必须将此十六进制字符串转换回字节:

// Instead of this: byte[] encryptedBytes = src.getBytes(); 
// Do this: 
byte[] encryptedBytes = DatatypeConverter.parseHexBinary(src); 

而你返回ByteArrayInputStreamtoString()表示,但实际上你需要的是buf变量(因为它会包含解密数据)。 所以你decryptString方法应该返回:

// Instead of this: return bais.toString(); 
// do this: 
return new String(buf); 

注意:为你转换String字节,并且字节回String,你可能会面临一些编码问题。为防止这种情况发生,建议始终使用相同的编码方式进行这两种转换。在这种情况下,你可以做以下(假设你想使用UTF-8,例如)。

encryptString

cout.write(src.getBytes("UTF-8")); // instead of cout.write(src.getBytes()); 

decryptString

return new String(buf, "UTF-8"); // instead of return new String(buf); 

这应该与任何编码,只要您使用相同的两种方法工作。

+0

是的,我终于明白了!非常感谢它..谢谢哥们 – noobie