javax.crypto.BadPaddingException: Given final block not properly padded - DES Decryption - java

I am trying to decrypt a message on server - the error what I got is
Encryption technique used - DES.
--Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
I am having a very difficult time trying to solve this problem,
any help will be appreciated
class TCPClient {
public static void main(String argv[]) throws Exception {
byte[] sentence, textEncrypted;
String modifiedSentence;
String password;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
password = "Passcode";
byte[] salt = new byte[64];
Random rnd = new Random();
rnd.nextBytes(salt);
byte[] data = deriveKey(password, salt, 64);
// BufferedReader inFromServer = new BufferedReader(new
// InputStreamReader(clientSocket.getInputStream()));
System.out.println("Enter the Data to be transmisted to server\n");
sentence = inFromUser.readLine().getBytes();
SecretKey desKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec(data));
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, desKey);
textEncrypted = cipher.doFinal(sentence);
outToServer.writeBytes(new String(textEncrypted) + '\n');
clientSocket.close();
}
public static byte[] deriveKey(String password, byte[] salt, int keyLen) {
SecretKeyFactory kf = null;
try {
kf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
KeySpec specs = new PBEKeySpec(password.toCharArray(), salt, 1024, keyLen);
SecretKey key = null;
try {
key = kf.generateSecret(specs);
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return key.getEncoded();
}
}
Server side code
class TCPServer {
public static void main(String argv[]) throws Exception {
String password = null;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(6789);
while (true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
password = "Passcode";
byte[] salt = new byte[64];
Random rnd = new Random();
rnd.nextBytes(salt);
byte[] data = deriveKey(password, salt, 64);
byte [] EncyptedText = inFromClient.readLine().getBytes();
System.out.println("Received Encrypted message " + EncyptedText);
SecretKey desKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec(data));
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, desKey);
// Decrypt the text
System.out.println("Text Received " + EncyptedText);
byte[] textDecrypted = cipher.doFinal(EncyptedText);
System.out.println("Text Decryted : " + new String(textDecrypted));
}
}
public static byte[] deriveKey(String password, byte[] salt, int keyLen) {
SecretKeyFactory kf = null;
try {
kf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
KeySpec specs = new PBEKeySpec(password.toCharArray(), salt, 1024, keyLen);
SecretKey key = null;
try {
key = kf.generateSecret(specs);
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return key.getEncoded();
}
}

You will lose data doing this:
outToServer.writeBytes(new String(textEncrypted) + '\n');
besides that, it's not necessary. Ciphertext is not really text for modern ciphers, it's binary. And as sockets provide binary InputStreams and OutputStreams there is simply no reason to convert the ciphertext to strings either. All that is required is to convert possible input strings to binary (using the same encoding on both the client and server, of course - UTF-8 is preferred nowadays).

Related

Why am I getting an illegalBlockSizeException when trying to decrypt this message?

I am creating a server (Responder B) and client (Initiator A) which will exchange encrypted messages that will be decrypted on the receiving end. However, when I send an encrypted message from responder B to initiator a, I am getting the "Input length must be multiple of 8 when decrypting with the padded cipher" error.
Here is the server/Responder B code:
public class ResponderB {
protected static String masterKey = "NETWORK SECURITY";
protected String identityA;
protected String ciphertext;
private DataOutputStream out;
private Socket socket;
private ServerSocket server;
private DataInputStream in;
public ResponderB(int port, String ciphertext) {
this.ciphertext = ciphertext;
try {
server = new ServerSocket(port);
System.out.println("Responder started");
System.out.println("Waiting for initiator ...");
socket = server.accept();
System.out.println("Responder accepted");
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
String line = "";
//System.out.println("ResponderB ciphertext: "+this.ciphertext);
try {
line = in.readUTF();
this.identityA = line;
System.out.println("Identity Recieved");
System.out.println("Initiator Identity: "+this.identityA);
this.identityA = encrypt(this.identityA, masterKey);
this.ciphertext = this.identityA + " " + this.ciphertext;
System.out.println("Message Two Ciphertext in bytes: "+this.ciphertext.getBytes());
System.out.println("Message Two Ciphertext: "+this.ciphertext);
out.writeUTF(this.ciphertext);
}catch(IOException i){
System.out.println(i);
}
System.out.println("Closing connection");
//close connection
socket.close();
in.close();
}catch(IOException i){
System.out.println(i);
}
}
public static void main(String args[]){
String sessionKey = "SESSION";
String ciphertext1 = ""; String ciphertext2 = "";
String identityB = "RESPONDER B";
ciphertext1 = encrypt(identityB, masterKey);
ciphertext2 = encrypt(sessionKey, masterKey);
String cleartext = ciphertext1 + " " + ciphertext2;
ResponderB initiator = new ResponderB(6666, cleartext);
}}
This is the client/initiator a code:
public class InitiatorA {
private String identity = "INITIATOR A";
private String masterKey = "NETWORK SECURITY";
private String ciphertext, plaintext, temptext, sessionKey;
private Socket socket;
private BufferedReader input;
private DataOutputStream out;
private DataInputStream in;
public InitiatorA(String address, int port) {
// try to establish a connection
try {
socket = new Socket(address, port);
System.out.println("Connected");
//ready the input reader
input = new BufferedReader(new InputStreamReader(System.in));
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
out = new DataOutputStream(socket.getOutputStream());
// String to read a message from the input
String line = "";
String buffer = "";
//line = input.readLine(); // Reads line from keyboard
System.out.println("Cleartext of message 1: " + this.identity);
out.writeUTF(this.identity); // writes it to the output stream
buffer = in.readUTF();
this.ciphertext = buffer;
System.out.println("The received ciphertext of message 2: " + this.ciphertext);
String[] tokens = this.ciphertext.split("\\s+");
for(int i = 0; i < tokens.length; i++){
this.plaintext = this.plaintext + decrypt(tokens[i], this.masterKey);
}
System.out.println("The decrypted message 2: " + this.plaintext);
} catch (IOException i) {
System.out.println(i);
}
}
public static void main(String args[]) {
InitiatorA responder = new InitiatorA("127.0.0.1", 6666);
}}
Finally, these are the encrypt and decrypt methods I am using, the algorithm to encrypt and decrypt the messages is DES, and I am using a custom key (masterKey) that is being converted to a secret Key from a string, One thing I noticed is that the byte [] of the ciphertext being transmitted is changing from the server to the client-side, but the actual text in the cipher text remains the same.
Another exception I am getting is the: "
javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption." But I don't see how a bad key would be in place here since the same string is being used on the server and client-side.
public static String encrypt(String plain, String key) {
String plaintext, ciphertext = "", plaintext1;
byte[] plaintextByte, plaintext1Byte, ciphertextByte, keyByte;
plaintext = plain;
try {
keyByte = key.getBytes();
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey desKey = keyFactory.generateSecret(new DESKeySpec(keyByte));
plaintextByte = plaintext.getBytes();
Cipher desCipher;
desCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
desCipher.init(Cipher.ENCRYPT_MODE, desKey);
ciphertextByte = desCipher.doFinal(plaintextByte);
ciphertext = new String(ciphertextByte, StandardCharsets.UTF_8);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException i) {
System.out.println(i);
}
return ciphertext;
}
public static String decrypt(String cipher, String key) {
String plaintext = "", ciphertext, plaintext1="";
byte[] plaintextByte, plaintext1Byte, ciphertextByte, keyByte;
try {
keyByte = key.getBytes();
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey desKey = keyFactory.generateSecret(new DESKeySpec(keyByte));
Cipher desCipher;
desCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
desCipher.init(Cipher.DECRYPT_MODE, desKey);
plaintext1Byte = desCipher.doFinal(cipher.getBytes());
plaintext1 = new String(plaintext1Byte, StandardCharsets.UTF_8);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException i) {
System.out.println(i);
}
return plaintext1;
}
Thank you in advance for the help.

Input length must be multiple of 8 when decrypting with padded cipher

I have a client/server application that encrypts or decrypts a message both on the client-side and server-side. However on decryption I keep getting the following error from the StackTrace
Input length must be multiple of 8 when decrypting with padded cipher
Following is the code from both the Server and Client classes.
The thing is I have tried using ("DES/CBC/PKCS5Padding") and ("UTF-8") but still haven't been able to fix said issue.
Any help would be appreciated thanks?
public class ServerApp {
public static byte[] encrypt(String input, Key k) {
try {
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, k);
byte[] data = input.getBytes();
byte[] result = cipher.doFinal(data);
return result;
} catch (Exception ex) {
return null;
}
}
public static String decrypt(byte[] cipher, Key k) {
try {
Cipher cipher1 = Cipher.getInstance("DES");
cipher1.init(Cipher.DECRYPT_MODE, k);
byte[] original = cipher1.doFinal(cipher);
return new String(original);
} catch (Exception ex) {
return null;
//Logger.getLogger(DES.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) throws NoSuchAlgorithmException {
try {
Key key=KeyGen.getSecretKey();
ServerSocket ser = new ServerSocket(3333);
System.out.println("Server Started");
Socket client = ser.accept();
DataInputStream in = new DataInputStream(client.getInputStream());
DataOutputStream out = new DataOutputStream(client.getOutputStream());
Scanner scan = new Scanner(System.in);
// SecretSocket sc = new SecretSocket(client, KeyGen.getSecretKey());
String serMsg, cliMsg, plain;
// OutputStream sout = sc.getOutputStream();
// InputStream sin = sc.getInputStream();
do {
System.out.print("You say: ");
serMsg = scan.nextLine();
// sout.write(serMsg.getBytes());
// System.out.println("cli server "+sin.read());
byte[] ci = encrypt(serMsg, KeyGen.getSecretKey());
System.out.println("encrypt " +ci.toString());
out.writeUTF(ci.toString());
plain = decrypt(ci, KeyGen.getSecretKey() );
System.out.println("decrypt " + plain);
} while (!serMsg.equals("end"));
client.close();
ser.close();
} catch (IOException ex) {
Logger.getLogger(ServerApp.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public class ClientApp {
public static byte[] encrypt(String input, Key k) {
try {
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, k);
byte[] data = input.getBytes();
byte[] result = cipher.doFinal(data);
return result;
} catch (Exception ex) {
return null;
}
}
public static String decrypt(byte[] cipher, Key k) {
try {
Cipher cipher1 = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher1.init(Cipher.DECRYPT_MODE, k);
byte[] original = cipher1.doFinal(cipher);
return new String(original);
} catch (Exception ex) {
return null;
//Logger.getLogger(DES.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
try {
Socket s = new Socket("localhost", 3333);
DataInputStream in = new DataInputStream(s.getInputStream());
DataOutputStream out = new DataOutputStream(s.getOutputStream());
Scanner scan = new Scanner(System.in);
String serMsg, cliMsg, plain;
do {
System.out.println("server server "+in.readUTF());
serMsg = in.readUTF();
System.out.println("enc: " + serMsg);
plain = decrypt(serMsg.getBytes("UTF-8"), KeyGen.getSecretKey());
System.out.println("Server says: " + plain);
} while (!serMsg.equals("end"));
s.close();
} catch (IOException ex) {
Logger.getLogger(ClientApp.class.getName()).log(Level.SEVERE, null, ex);
}
}
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, k);
byte[] data = input.getBytes();
byte[] result = cipher.doFinal(data);
Using DES without IV you are implicitly using DES/ECB/PKCS5Padding.
do not print a byte array directly. Java will output only printable characters. Always encode and decode a byte array when printing (Hex or Base64 are the most common encodings)
Here is an example project
Base64.getEncoder().encodeToString(byteArray)
I hope you are aware DES is considered a weak cipher today and should be used only for backward compatibility.

Java : can't decrypt what I encrypt

sorry if my question is silly but I'm learning java, I'm working on a project where encrypt and decrypt is needed I'm done with the code and the button for encrypting is fully functional but when I try to decrypt (different button) there is an error all the time.
encrypt code
path = chooser.getSelectedFile();
String x = path.toString();
try {
Scanner scanner = new Scanner(new File(x));
content = scanner.useDelimiter("\\Z").next();
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
try{
KeyGenerator keygenerator = KeyGenerator.getInstance("DES");
SecretKey myDesKey = keygenerator.generateKey();
Cipher desCipher;
desCipher = Cipher.getInstance("DES");
byte[] text = content.getBytes("UTF8");
desCipher.init(Cipher.ENCRYPT_MODE, myDesKey);
byte[] textEncrypted = desCipher.doFinal(text);
String s = new String(textEncrypted);
try {
File statText = new File(x);
FileOutputStream is = new FileOutputStream(statText);
OutputStreamWriter osw = new OutputStreamWriter(is);
Writer w = new BufferedWriter(osw);
w.write(s);
w.close();
}
catch (IOException e3) {
JOptionPane.showMessageDialog(null, "something is wrong with the txt file");
}
}catch(Exception e1)
{
System.out.println("En");
}
and here is the decrypt part :
path = chooser.getSelectedFile();
String x = path.toString();
try {
Scanner scanner = new Scanner(new File(x));
content = scanner.useDelimiter("\\Z").next();
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
try{
KeyGenerator keygenerator = KeyGenerator.getInstance("DES");
SecretKey myDesKey = keygenerator.generateKey();
Cipher desCipher;
desCipher = Cipher.getInstance("DES");
byte[] text = content.getBytes("UTF8");
byte[] textEncrypted = desCipher.doFinal(text);
desCipher.init(Cipher.DECRYPT_MODE, myDesKey);
byte[] textDecrypted = desCipher.doFinal(textEncrypted);
String s = new String(textDecrypted);
System.out.println(s);
}catch(Exception e1)
{
System.out.println("De"); /* here we go this is my error*/
}
the error at the second code "catch(Exception e1)"
I see two problems in your code. In your first part, you only sent the encrypted message and the receiver would not decrypt because you didn't send your key to the receiver. The second problem is you use String s = new String(textEncrypted);, you should send the textEncrypted instead of the string because converting bytes to string may lost some information due to encoding.
In your second part, you should call desCipher.init(Cipher.ENCRYPT_MODE, myDesKey); before encryption.
problem solved
encrypt code :
path = chooser.getSelectedFile();
String x = path.toString();
try {
scanner = new Scanner(new File(x));
content = scanner.useDelimiter("\\Z").next();
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
try{
String desKey = "0123456789abcdef";
byte[] keyBytes = DatatypeConverter.parseHexBinary(desKey);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey key = factory.generateSecret(new DESKeySpec(keyBytes));
desCipher = Cipher.getInstance("DES");
byte[] text = content.getBytes();
desCipher.init(Cipher.ENCRYPT_MODE, key);
byte[] textEncrypted = desCipher.doFinal(text);
String s = new String(textEncrypted);
try {
File statText = new File(x);
FileOutputStream is = new FileOutputStream(statText);
OutputStreamWriter osw = new OutputStreamWriter(is);
Writer w = new BufferedWriter(osw);
w.write(s);
w.close();
}
catch (IOException e3) {
JOptionPane.showMessageDialog(null, "something is wrong with the txt file");
}
}catch(Exception e1)
{
System.out.println("relax and try again");
}
Decrypt code:
path = chooser.getSelectedFile();
String x = path.toString();
try {
Scanner scanner = new Scanner(new File(x));
content = scanner.useDelimiter("\\Z").next();
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
try{
String desKey = "0123456789abcdef";
byte[] keyBytes = DatatypeConverter.parseHexBinary(desKey);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey key = factory.generateSecret(new DESKeySpec(keyBytes));
desCipher = Cipher.getInstance("DES");
byte[] text = content.getBytes();
desCipher.init(Cipher.DECRYPT_MODE, key);
byte[] textEncrypted = desCipher.doFinal(text);
String s = new String(textEncrypted);
try {
File statText = new File(x);
FileOutputStream is = new FileOutputStream(statText);
OutputStreamWriter osw = new OutputStreamWriter(is);
Writer w = new BufferedWriter(osw);
w.write(s);
w.close();
}
catch (IOException e3) {
JOptionPane.showMessageDialog(null, "something is wrong with the txt file");
}
}catch(Exception e24)
{
System.out.println("relax and try again");
}
Thank you every one.

Android javax.crypto.BadPaddingException: pad block corrupted

I am trying to decrypt a file using the following code:
Uri targURI = Uri.parse("content://xxxx/yyy.txt");
try {
InputStream content = getContentResolver().openInputStream(targURI);
BufferedReader reader1 = new BufferedReader(new InputStreamReader(content));
String line1;
String text = "";
while ((line1 = reader1.readLine()) != null) {
text+=line1;
}
Log.i("FILE ENCRYPTED", text);
String DECRYPTED = "";
DECRYPTED = decrypt(text);
Log.i("FILE DECRYPTED:", DECRYPTED);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public String decrypt(String paramString) throws Exception {
String md5_pin1 = "";
String md5_pin = MD5(md5_pin1);
SecretKeySpec keySpec = new SecretKeySpec(md5_pin.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] paramString1 = Base64.decode(paramString.getBytes(), 0);
byte[] paramstring2 = cipher.doFinal(paramString1);
String decoded = new String(paramstring2, "UTF-8");
return decoded;
}
#NonNull
public static String MD5(String paramString) throws Exception {
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
digest.update(paramString.getBytes());
byte messageDigest[] = digest.digest();
StringBuffer hexString = new StringBuffer();
int i=0;
while( i < messageDigest.length) {
String str = Integer.toHexString( messageDigest[i] & 0xFF );
if (str.length() == 1) {
hexString.append("0");
}
hexString.append(str);
i += 1;
}
return hexString.toString();
}
as it is showed the file is accessed using a content provider, and stored in a String variable, and actually the correct string value is stored (encrypted data).
The way to decrypt it is to get a seed (empty space in this case), and then use MD5 digest, then use that value to encrypt/decrypt the cleartext.
However whenever the code reaches: String decoded = new String(paramstring2, "UTF-8"); the error message: pad block corrupted is thrown.
Any ideas what I am doing wrong?
Avoid using default padding for cipher as it may be different on different environment.
Try the following code:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
Also use the same padding for encrypting the file.
You can use the following methods:
private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = new byte[cipher.getBlockSize()];
IvParameterSpec ivParams = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), ivParams);
return cipher.doFinal(data);
}
private static byte[] decrypt(byte[] encrypted, byte[] key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] ivByte = new byte[cipher.getBlockSize()];
IvParameterSpec ivParamsSpec = new IvParameterSpec(ivByte);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), ivParamsSpec);
return cipher.doFinal(encrypted);
}
This was not a problem related to coding.
Please disregard this question

Send file encrypted (Server) and receive file decrypted (Client) with AES 256

Im sending a file from Server to a Client but i need to send a encrypted file with AES 256 and receive a original for client use in diferente machine.
I want use 2 string to generate a SHA256 for example: "fruit" and "car29".
After generate this key I want to use this key as secretkey to encrypt with AES256.The client and server know the two strings.
My server code:
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();
}
}
}
My client code:
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();
}
}
Thanks in advance!
There's some function I write for you, check it out.
For generating HASH/Digest:
public byte[] generateHASH(byte[] message) throws Exception {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
byte[] hash = messageDigest.digest(message);
return hash;
}
For Encryption:
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;
}
For Decryption:
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;
}
Note:
If you use CBC mode, then both encrypt() and decrypt() use same iv, otherwise you don't need iv, and of course key is same for both.
Your key generation process is naive. You better use RSA public key encryption for key exchange or Diffie–Hellman key exchange method for secret key transfer.
I would suggest you to use SSL. The data encryption comes by default. The SSL handshake takes care of generating and exchanging the encryption keys and subsequently encrypting the data from the source and decrypting it at the receiving end. All this happens at the transport layer and the application does not have to bother or do anything explicit except for configuring it to use SSL.

Categories