С помощью нижеприведенного класса можно легко зашифровать некоторую строку (например пароль) с использование алгоритма DES, и затем при желании расшифровать её. При этом секретный ключ сохранен в теле класса, так что строку можно будет расшифровать даже после перезапуска программы.
UPD 06.02.13
Выкладываю обновленную версию класса. В новой версии используется сторонняя билиотека Apache Codec http://commons.apache.org/codec/, также методы класса сделаны нестатическими, благодаря чему стало возможным с данным классом создавать несколько шифрователей с разными ключами или алгоритмами в одном приложении и динамически менять ключ шифрования. Минимальная версия jdk - 1.7, однако после внесения небольших изменений может использоваться и на более ранних версиях java.
Пример использования нового класса
// Файл SecuritySettings.java
package security;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
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.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
/**
*
* @author Cloud
*/
public final class SecuritySettings {
private final static class MySecretKey implements SecretKey {
private byte[] key = new byte[]{1, 2, 3, 4, 5, 6, 7, 8}; // ключ
// не должен иметь длину более 8 байт, для безопасного шифрования его
// необходимо изменить
public String getAlgorithm() {
return "DES";
}
public String getFormat() {
return "RAW";
}
public byte[] getEncoded() {
return key;
}
}
private static SecretKey key;
private static Cipher ecipher;
private static Cipher dcipher;
static {
try {
key = new MySecretKey();
ecipher = Cipher.getInstance("DES");
dcipher = Cipher.getInstance("DES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
} catch (InvalidKeyException ex) {
Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchPaddingException ex) {
Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* Функция шифрования
* @param str строка открытого текста
* @return зашифрованная строка в формате Base64
*/
public static String encrypt(String str) {
try {
byte[] utf8 = str.getBytes("UTF8");
byte[] enc = ecipher.doFinal(utf8);
return new sun.misc.BASE64Encoder().encode(enc);
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
} catch (BadPaddingException ex) {
Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
/**
* Функция расшифрования
* @param str зашифрованная строка в формате Base64
* @return расшифрованная строка
*/
public static String decrypt(String str) {
try {
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
byte[] utf8 = dcipher.doFinal(dec);
return new String(utf8, "UTF8");
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
} catch (BadPaddingException ex) {
Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}
UPD 06.02.13
Выкладываю обновленную версию класса. В новой версии используется сторонняя билиотека Apache Codec http://commons.apache.org/codec/, также методы класса сделаны нестатическими, благодаря чему стало возможным с данным классом создавать несколько шифрователей с разными ключами или алгоритмами в одном приложении и динамически менять ключ шифрования. Минимальная версия jdk - 1.7, однако после внесения небольших изменений может использоваться и на более ранних версиях java.
// Файл StringCrypter.java
package rva.common.util;
import java.io.IOException;
import org.apache.commons.codec.binary.Base64;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
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;
/**
* Класс для шифрования и дешифрования строк
* Использует библиотеку Apache Codec http://commons.apache.org/codec/
* @author Рудницкий Валентин
*/
public class StringCrypter {
/**
* Упрощенный конструктор. Создает StringCrypter с ключом DESSecretKey со значением по умолчанию (не рекомендуется)
*/
public StringCrypter() {
this(new byte[]{1, 2, 3, 4, 5, 6, 7, 8});
}
/**
* Упрощенный конструктор. Создает StringCrypter с ключом
* DESSecretKey (алгоритм шифрования DES) со значением key.
* Ключ key должен иметь длину 8 байт
*/
public StringCrypter(byte[] key) {
try {
updateSecretKey(new DESSecretKey(key));
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException ex) {
throw new IllegalArgumentException(ex.getMessage());
}
}
public StringCrypter(SecretKey key) throws NoSuchPaddingException,
NoSuchAlgorithmException,
InvalidKeyException {
updateSecretKey(key);
}
private void updateSecretKey(SecretKey key) throws NoSuchPaddingException,
NoSuchAlgorithmException,
InvalidKeyException {
ecipher = Cipher.getInstance(key.getAlgorithm());
dcipher = Cipher.getInstance(key.getAlgorithm());
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
}
public static class DESSecretKey implements SecretKey {
private final byte[] key;
/**
* ключ должен иметь длину 8 байт
*/
public DESSecretKey(byte[] key) {
this.key = key;
}
@Override
public String getAlgorithm() {
return "DES";
}
@Override
public String getFormat() {
return "RAW";
}
@Override
public byte[] getEncoded() {
return key;
}
}
private Cipher ecipher;
private Cipher dcipher;
/**
* Функция шифрования
*
* @param str строка открытого текста
* @return зашифрованная строка в формате Base64
*/
public String encrypt(String str) {
try {
byte[] utf8 = str.getBytes("UTF8");
byte[] enc = ecipher.doFinal(utf8);
return Base64.encodeBase64String(enc);
} catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException ex) {
Logger.getLogger(StringCrypter.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
/**
* Функция дешифрования
*
* @param str зашифрованная строка в формате Base64
* @return расшифрованная строка
*/
public String decrypt(String str) {
try {
byte[] dec = Base64.decodeBase64(str);
byte[] utf8 = dcipher.doFinal(dec);
return new String(utf8, "UTF8");
} catch (IllegalBlockSizeException | BadPaddingException | IOException ex) {
Logger.getLogger(StringCrypter.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}
Пример использования нового класса
// создаем экземпляр класса StringCrypter с ключем шифрования
StringCrypter crypter=new StringCrypter(new byte[]{1,4,5,6,8,9,7,8});
String testStr = "forCryptString";
// шифрование
String encBase64Str = crypter.encrypt(testStr);
// дешифрование
String decryptedStr = crypter.decrypt(encBase64Str);