使用AES 256发送文件加密(服务器)和接收文件解密(客户端)

时间:2015-07-28 10:56:02

标签: java encryption cryptography

我将文件从服务器发送到客户端,但我需要发送一个带有AES 256的加密文件,并在diferente机器上接收供客户使用的原件。 我想用2个字符串来生成SHA256,例如:“fruit”和“car29”。 生成此密钥后,我想使用此密钥作为密钥来使用AES256加密。客户端和服务器知道这两个字符串。

我的服务器代码:

public final static int SOCKET_PORT = 4444;
public final static String FILE_TO_SEND = "C:\\file.txt";

public static void main(String[] args) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {

    FileInputStream fis = null;
    BufferedInputStream bis = null;
    OutputStream os = null;
    ServerSocket servsock = null;
    Socket sock = null;
    try {
        servsock = new ServerSocket(SOCKET_PORT);
        while (true) {
            System.out.println("Waiting...");
            try {
                sock = servsock.accept();
                System.out.println("Accepted connection : " + sock);
                // send file
                File myFile = new File(FILE_TO_SEND);
                byte[] mybytearray = new byte[(int) myFile.length()];
                fis = new FileInputStream(myFile);
                bis = new BufferedInputStream(fis);
                bis.read(mybytearray, 0, mybytearray.length);
                os = sock.getOutputStream();
                System.out.println("Sending " + FILE_TO_SEND + "(" + mybytearray.length + " bytes)");
                os.write(mybytearray, 0, mybytearray.length);
                os.flush();
                System.out.println("Done.");
            } finally {
                if (bis != null) {
                    bis.close();
                }
                if (os != null) {
                    os.close();
                }
                if (sock != null) {
                    sock.close();
                }
            }
        }
    } finally {
        if (servsock != null) {
            servsock.close();
        }
    }
}

我的客户代码:

public final static int SOCKET_PORT = 4444;
public final static String SERVER = "127.0.0.1";
public final static String FILE_TO_RECEIVED = "C:\\file.txt";
public final static int FILE_SIZE = 6022386;
public static void main (String [] args ) throws IOException {
int bytesRead;
int current = 0;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
Socket sock = null;
try {
      sock = new Socket(SERVER, SOCKET_PORT);
      System.out.println("Connecting...");
      // receive file
      byte [] mybytearray  = new byte [FILE_SIZE];
      InputStream is = sock.getInputStream();
      fos = new FileOutputStream(FILE_TO_RECEIVED);
      bos = new BufferedOutputStream(fos);
      bytesRead = is.read(mybytearray,0,mybytearray.length);
      current = bytesRead;
      do {
         bytesRead =
            is.read(mybytearray, current, (mybytearray.length-current));
         if(bytesRead >= 0) current += bytesRead;
      } while(bytesRead > -1);
      bos.write(mybytearray, 0 , current);
      bos.flush();
      System.out.println("File " + FILE_TO_RECEIVED
          + " downloaded (" + current + " bytes read)");
    }
    finally {
      if (fos != null) fos.close();
      if (bos != null) bos.close();
      if (sock != null) sock.close();
    }
  }

提前致谢!

2 个答案:

答案 0 :(得分:0)

我为你写的一些功能,请查看。

用于生成 HASH / Digest

public byte[] generateHASH(byte[] message) throws Exception {
    MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
    byte[] hash = messageDigest.digest(message);
    return hash;
}

对于 加密

public byte[] encrypt(byte[] msg, byte[] key, byte[] iv) throws Exception {
    //prepare key
    SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

    //prepare cipher
    String cipherALG = "AES/CBC/PKCS5padding"; // use your preferred algorithm 
    Cipher cipher = Cipher.getInstance(cipherALG);
    String string = cipher.getAlgorithm();

    //as iv (Initial Vector) is only required for CBC mode
    if (string.contains("CBC")) {
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);      
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
    } else {
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
    }

    byte[] encMessage = cipher.doFinal(msg);        
    return encMessage;
}

解密

public byte[] decrypt(byte[] encMsgtoDec, byte[] key, byte[] iv) throws Exception {
    //prepare key
    SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");

    //prepare cipher
    String cipherALG = "AES/CBC/PKCS5padding"; // use your preferred algorithm 
    Cipher cipher = Cipher.getInstance(cipherALG);
    String string = cipher.getAlgorithm();

    //as iv (Initial Vector) is only required for CBC mode
    if (string.contains("CBC")) {
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);      
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
    } else {
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
    }

    byte[] decMsg = cipher.doFinal(encMsgtoDec);        
    return decMsg;
}

注意

  • 如果您使用CBC模式,则encrypt()decrypt()都使用相同的iv,否则您不需要iv,当然key 1}}对于两者都是相同的。

  • 您的密钥生成过程很幼稚。您最好使用RSA公钥加密进行密钥交换,或使用Diffie–Hellman key exchange方法进行密钥传输。

答案 1 :(得分:0)

我建议你使用SSL。数据加密默认为。 SSL握手负责生成和交换加密密钥,随后加密来自源的数据并在接收端对其进行解密。所有这些都发生在传输层,除了将其配置为使用SSL之外,应用程序不必费心或做任何明确的事情。