/**
* Copyright 2009 Marc Stogaitis and Mimi Sun
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gmote.server;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import org.gmote.server.settings.SystemPaths;
//import sun.misc.BASE64Decoder;
//import sun.misc.BASE64Encoder;
/**
* Based on the example code found at:
* http://www.devx.com/Java/10MinuteSolution/21385/1954 from Javid Jamae
*
* Allows us to encrypt our passwords when storing it to a file. This is not
* secure since the key can be reverse engineering out of this file but we
* assume that the user's computer is reasonably secure.
*
*/
public class StringEncrypter {
private static Logger LOGGER = Logger.getLogger(StringEncrypter.class.getName());
public static final String DES_NAME = "DES";
/**
* Key used during encryption. This could easily be reversed engineered.
*/
public static final String SECRET = "ABKDIEKF3Ikdiekdjfow FKEIDKSI fkeijklas2f";
private KeySpec keySpec;
private SecretKeyFactory keyFactory;
private Cipher cipher;
private static final String UNICODE_FORMAT = "UTF8";
public static void writePasswordToFile(String password) throws EncryptionException {
try {
StringEncrypter se = new StringEncrypter();
byte[] cipherText = se.encrypt(password);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(SystemPaths.PASSWORD.getFullPath()));
oos.writeObject(new ByteContainer(cipherText));
oos.close();
} catch (FileNotFoundException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new EncryptionException(e);
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new EncryptionException(e);
} catch (InvalidKeyException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new EncryptionException(e);
} catch (NoSuchAlgorithmException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new EncryptionException(e);
} catch (NoSuchPaddingException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new EncryptionException(e);
} catch (InvalidKeySpecException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new EncryptionException(e);
} catch (IllegalBlockSizeException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new EncryptionException(e);
} catch (BadPaddingException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw new EncryptionException(e);
}
}
public static synchronized String readPasswordFromFile() {
ObjectInputStream is;
try {
is = new ObjectInputStream(new FileInputStream(SystemPaths.PASSWORD.getFullPath()));
ByteContainer cipherText;
cipherText = (ByteContainer) is.readObject();
is.close();
StringEncrypter se = new StringEncrypter();
return se.decrypt(cipherText.getCipherText());
} catch (FileNotFoundException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
} catch (InvalidKeyException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
} catch (NoSuchAlgorithmException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
} catch (NoSuchPaddingException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
} catch (InvalidKeySpecException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
} catch (IllegalBlockSizeException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
} catch (BadPaddingException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
} catch (ClassNotFoundException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
}
return "";
}
public StringEncrypter() throws UnsupportedEncodingException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchPaddingException {
byte[] keyAsBytes = SECRET.getBytes(UNICODE_FORMAT);
keySpec = new DESKeySpec(keyAsBytes);
keyFactory = SecretKeyFactory.getInstance(DES_NAME);
cipher = Cipher.getInstance(DES_NAME);
}
private byte[] encrypt(String unencryptedString) throws InvalidKeySpecException,
InvalidKeyException, UnsupportedEncodingException, IllegalBlockSizeException,
BadPaddingException {
SecretKey key = keyFactory.generateSecret(keySpec);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cleartext = unencryptedString.getBytes(UNICODE_FORMAT);
byte[] ciphertext = cipher.doFinal(cleartext);
return ciphertext;
}
private String decrypt(byte[] ciphertext) throws InvalidKeySpecException,
InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException {
SecretKey key = keyFactory.generateSecret(keySpec);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] cleartext = cipher.doFinal(ciphertext);
return bytes2String(cleartext);
}
private static String bytes2String(byte[] bytes) {
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
stringBuffer.append((char) bytes[i]);
}
return stringBuffer.toString();
}
}