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;
}
}