I am creating a properties JFrame for use in my GUI, and I wanted to save all of the data inputted into the frame into a file called config.properties. The Poperties class already has several convienent methods to save, load, and get properties, but it stores all the data in plain text format. This is fine for most of the data, but for the password, it is not. I wanted to encrypt the password into "DES" (some coding algorithm) and save it into the file. This has gone well... but the loading of the property file on the next startup throws a BadPaddingException.

javax.crypto.BadPaddingException: Given final block not properly padded
	at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
	at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
	at com.sun.crypto.provider.DESCipher.engineDoFinal(DashoA13*..)
	at javax.crypto.Cipher.doFinal(DashoA13*..)
	at KidsTopFrame$KTPropFrame.decrypt(KidsTopFrame.java:312)
	at KidsTopFrame$KTPropFrame.readConfig(KidsTopFrame.java:283)
	at KidsTopFrame$KTPropFrame.<init>(KidsTopFrame.java:274)
	at KidsTopFrame.<init>(KidsTopFrame.java:38)
	at KidsTopDriver.main(KidsTopDriver.java:7)

(KidsTopFrame is the public class... KTPropFrame is a private class inside of KidsTopFrame)

The apparent culprit? The decrypt() method... I have no idea why this is giving me trouble.

What I have so far: (NOTE: this is an internal private class in another of my GUI classes. For brevity, I have excluded the none pertaining code (I think... Please point out any inconsistancy and I will do my best.))

//the properties panel
private class KTPropFrame extends JFrame {
      
	private JLabel blank, pass1Label, pass2Label, progLabel;
	private JTextField pass1Field, pass2Field;
	private JLabel[] paths, names;
	private JButton[] buttons;
	private JTextField[] nameFields, pathFields;
	private Container container;
	private JButton saveButton;
	private KeyGenerator kg;
	private Key key;
	
	public KTPropFrame() {
		super("Properties");
		container = getContentPane();
		
		setLayout(new GridLayout(20, 5, 5, 5));
		
		Security.addProvider(new com.sun.crypto.provider.SunJCE());
		kg = null;
		key = null;
		try {
			kg = KeyGenerator.getInstance("DES");
			key = kg.generateKey();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
		blank = createAndAddLabel("");
		pass1Label = createAndAddLabel("Set Password: ");
		pass1Field = createAndAddTextField();
		blank = createAndAddLabel("");
		blank = createAndAddLabel("");
		
		blank = createAndAddLabel("");
		pass2Label = createAndAddLabel("Confirm Password: ");
		pass2Field = createAndAddTextField();
		blank = createAndAddLabel("");
		blank = createAndAddLabel("");
		
		progLabel = createAndAddLabel("Programs:");
		blank = createAndAddLabel("");
		blank = createAndAddLabel("");
		blank = createAndAddLabel("");
		blank = createAndAddLabel("");
		
		paths = new JLabel[ROWS * COLUMNS];
		names = new JLabel[ROWS * COLUMNS];
		buttons = new JButton[ROWS * COLUMNS];
		nameFields = new JTextField[ROWS * COLUMNS];
		pathFields = new JTextField[ROWS * COLUMNS];
		
		for(int i = 0; i < ROWS * COLUMNS; i++) {
			names[i] = createAndAddLabel("Program "+(i+1)+": Name: ");
			nameFields[i] = createAndAddTextField();
			paths[i] = createAndAddLabel("Path: ");
			pathFields[i] = createAndAddTextField();
			buttons[i] = createAndAddButton("Browse", new ActionHandler(i));
		}
		
		blank = createAndAddLabel("");
		blank = createAndAddLabel("");
		blank = createAndAddLabel("");
		blank = createAndAddLabel("");
		blank = createAndAddLabel("");
		
		blank = createAndAddLabel("");
		blank = createAndAddLabel("");
		blank = createAndAddLabel("");
		blank = createAndAddLabel("");
		saveButton = createAndAddButton("Save", new SaveHandler());
		
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		setBounds((int)(screenSize.width * .125), (int)(screenSize.height * .125), (int)(screenSize.width * .75), (int)(screenSize.height * .75));
		setAlwaysOnTop(true);
		addWindowFocusListener(
			new WindowAdapter() {
				public void windowClosing(WindowEvent e) {
					JOptionPane.showMessageDialog(container, "Click the save button");
				}
			});
			
		readConfig();
	}
     
	//method to read the config file
	public void readConfig() {
		try {
			config.load(new FileInputStream(new File("config.properties")));
			String password = config.getProperty("Password");
			if (password != null || !password.equals(""))
				pass1Field.setText(decrypt(config.getProperty("Password")));
			pass2Field.setText(pass1Field.getText());
			for (int i = 0; i < ROWS * COLUMNS; i++) {
				nameFields[i].setText(config.getProperty("Program"+(i+1)+"Name"));
				pathFields[i].setText(config.getProperty("Program"+(i+1)+"Path"));
			}
		}
		catch (Exception e) {}
        }
      
	//method to encrypt the password
	private String encrypt(String s) {
		try {
			Cipher cipher = Cipher.getInstance("DES");
			cipher.init(Cipher.ENCRYPT_MODE,key);
			byte[] encrypted = cipher.doFinal(s.getBytes());
			return new String(encrypted);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	//method to decrypt the password
	private String decrypt(String s) {
		try {
			Cipher cipher = Cipher.getInstance("DES");
			cipher.init(Cipher.DECRYPT_MODE,key);
			byte[] decrypted = cipher.doFinal(s.getBytes());
			return new String(decrypted);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	private class ActionHandler implements ActionListener {
        
                                private int index;
          
		public ActionHandler(int i) {
	                	index = i;
                                }
         
		public void actionPerformed(ActionEvent e) {
			final JFileChooser fc = new JFileChooser();
			fc.setFileFilter(new FileNameExtensionFilter("Executable Files", "exe", "bat", "cmd", "com"));
			int returnVal = fc.showOpenDialog(container);
			if(returnVal == JFileChooser.APPROVE_OPTION){
				File executable = fc.getSelectedFile();
				pathFields[index].setText(executable.getAbsolutePath());
			}
		}
         	}
	
	private class SaveHandler implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			try {
				configFile.createNewFile();
				FileOutputStream fos = new FileOutputStream(configFile);
				if(pass1Field.getText().equals(pass2Field.getText()))
					config.setProperty("Password", encrypt(pass1Field.getText()));
				for (int i = 0; i < ROWS * COLUMNS; i++) {
					try {
						config.setProperty("Program"+(i+1)+"Name", "" + nameFields[i].getText());
						config.setProperty("Program"+(i+1)+"Path", "" + pathFields[i].getText());
					}  
					catch (NullPointerException npe) {
						continue;
					}
				}
			config.store(fos, "Properties file for KidsTop.  Do not modify.  If there is a problem, delete this file and run the software again.");
			fos.close();
			container.validate();
			prop.setVisible(false);
			}
			catch (IOException ioe) {
				ioe.printStackTrace();
				System.exit(0);
			}
                                }
	}
		
	//method to create and add a button to the panel
	private JButton createAndAddButton(String s, ActionListener li) {
		JButton temp = new JButton();
		temp.setText(s);
		temp.addActionListener(li);
		add(temp);
		return temp;
	}
      
	//method to create and add a label to the panel
	private JLabel createAndAddLabel(String s) {
		JLabel temp = new JLabel();
		temp.setText(s);
		add(temp);
		return temp;
	}
	
	//method to create and add a text field to the panel
	private JTextField createAndAddTextField() {
		JTextField temp = new JTextField();
		add(temp);
		return temp;
	}
}

I attached the full source code if you want to give it a shot.

Interestingly enough, when I created this file, I had no problems with it.

import javax.crypto.*;
import java.security.*;
import java.util.Properties;
import java.io.*;

public class CryptoTest {

	private KeyGenerator kg;
	private Key key;
	private Properties config;
	private File configFile;
	private String password;

	//constructor
	public CryptoTest() {
		//initialize
		config = new Properties();
		configFile = new File("config.properties");
		password = "password";
		
		Security.addProvider(new com.sun.crypto.provider.SunJCE());
		
		//throws off compiler error
		kg = null;
		key = null;
		
		try {
			configFile.createNewFile();//I don't care whether this is true or false.  Just makes sure that the file exists.
			kg = KeyGenerator.getInstance("DES");
			key = kg.generateKey();
		}
		catch (Exception e) { //so many exceptions... so little time XD
			e.printStackTrace();
		}
		
		//"save"
		config.setProperty("Password", encrypt(password));
	}
	
	public static void main(String[] args) {
		CryptoTest ct = new CryptoTest();
		System.out.println(ct);
    }
	
	//method used to encrypt password
	private String encrypt(String s) {
		try {
			Cipher cipher = Cipher.getInstance("DES");
			cipher.init(Cipher.ENCRYPT_MODE,key);
			byte[] encrypted = cipher.doFinal(s.getBytes());
			return new String(encrypted);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	//method to decrypt the password
	private String decrypt(String s) {
		try {
			Cipher cipher = Cipher.getInstance("DES");
			cipher.init(Cipher.DECRYPT_MODE,key);
			byte[] decrypted = cipher.doFinal(s.getBytes());
			return new String(decrypted);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
			return null;
	}
	
	public String toString() {
		return "Password: "+password+"\n"+
		"Encrypted: "+config.getProperty("Password")+"\n"+
		"Decrypted: "+decrypt(config.getProperty("Password"));
	}
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.