[Schmitzm-commits] r1794 - in trunk/schmitzm-core/src/main/java/de/schmitzm: crypt lang
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Wed Nov 23 20:19:27 CET 2011
Author: mojays
Date: 2011-11-23 20:19:26 +0100 (Wed, 23 Nov 2011)
New Revision: 1794
Modified:
trunk/schmitzm-core/src/main/java/de/schmitzm/crypt/CryptUtil.java
trunk/schmitzm-core/src/main/java/de/schmitzm/lang/ApplicationProps.java
Log:
ApplicationProps: new methods setEncrypted(.) and getStringDecrypted(.) to automatically encrypt/decrypt a value in property file
Modified: trunk/schmitzm-core/src/main/java/de/schmitzm/crypt/CryptUtil.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/crypt/CryptUtil.java 2011-11-23 17:36:20 UTC (rev 1793)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/crypt/CryptUtil.java 2011-11-23 19:19:26 UTC (rev 1794)
@@ -10,6 +10,7 @@
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
+import java.util.Properties;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
@@ -25,12 +26,66 @@
*/
public class CryptUtil {
+ /**
+ * An encrypted byte array can not be converted to string by
+ * {@code new String(byte[])} (e.g. to store the encrypted value
+ * in a {@link Properties} file)! This string creation destroys the
+ * encrypted value!<br>
+ * This method simply converts the byte array (the encrypted string)
+ * to a comma-separated list of the numeric byte values. This string
+ * can riskless stored in {@link Properties} file.<br>
+ * The other way around: {@link #convertWritableStringToEncryptedBytes(String)}
+ * method can be used to convert the comma-separated byte list back to the
+ * byte array (encrypted value).
+ * @param encryptedText encrypted text
+ * @see #convertWritableStringToEncryptedBytes(String)
+ */
+ public static String convertEncryptedBytesToWritableString(byte[] encryptedText) {
+ if ( encryptedText == null )
+ return null;
+ StringBuffer str = new StringBuffer();
+ for (int i=0; i<encryptedText.length; i++) {
+ if (i>0)
+ str.append(',');
+ str.append(encryptedText[i]);
+ }
+ return str.toString();
+ }
+
+ /**
+ * An encrypted byte array can not be converted to string by
+ * {@code new String(byte[])} (e.g. to store the encrypted value
+ * in a {@link Properties} file)! This string creation destroys the
+ * encrypted value!<br>
+ * {@link #convertEncryptedBytesToWritableString(byte[])} converts
+ * the byte array (the encrypted string) to a comma-separated list
+ * of the numeric byte values. This string can stored without risk
+ * in {@link Properties} file.<br>
+ * This method can be used to convert the string (comma-separated byte list)
+ * back to the byte array (encrypted value).
+ * @param byteList comma-separated list of numeric byte values
+ * @see #convertEncryptedBytesToWritableString(byte[])
+ */
+ public static byte[] convertWritableStringToEncryptedBytes(String byteList) {
+ if ( byteList == null )
+ return null;
+ try {
+ String[] strParts = byteList.split(",");
+ byte[] bytes = new byte[strParts.length];
+ for (int i=0; i<bytes.length; i++)
+ bytes[i] = Byte.parseByte(strParts[i]);
+ return bytes;
+ } catch (Exception err) {
+ throw new IllegalArgumentException("Byte list does not represent an encrypted string generated by convertEncryptedBytesToWritableString(.): "+byteList);
+ }
+ }
+
/**
* Creates a DEC cipher.
* @param cryptMode {@link Cipher#ENCRYPT_MODE} or {@link Cipher#DECRYPT_MODE}
* @param keyBytes encryption key
*/
- public static Cipher getDESCipher(final int cryptMode, final byte[] keyBytes) throws GeneralSecurityException {
+ public static Cipher createDESCipher(final int cryptMode, final byte[] keyBytes) throws GeneralSecurityException {
assert cryptMode == Cipher.ENCRYPT_MODE || cryptMode == Cipher.DECRYPT_MODE;
assert keyBytes != null;
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
@@ -88,7 +143,7 @@
*/
public static byte[] cryptBytes(byte[] inputStr, byte[] keyBytes, int cryptMode) {
try {
- Cipher cipher = getDESCipher(cryptMode, keyBytes);
+ Cipher cipher = createDESCipher(cryptMode, keyBytes);
return cryptBytes(inputStr, cipher);
} catch (Exception err) {
throw new RuntimeException(err);
Modified: trunk/schmitzm-core/src/main/java/de/schmitzm/lang/ApplicationProps.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/lang/ApplicationProps.java 2011-11-23 17:36:20 UTC (rev 1793)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/lang/ApplicationProps.java 2011-11-23 19:19:26 UTC (rev 1794)
@@ -40,9 +40,12 @@
import java.net.URL;
import java.util.Properties;
+import javax.crypto.Cipher;
+
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
+import de.schmitzm.crypt.CryptUtil;
import de.schmitzm.swing.ExceptionDialog;
import de.schmitzm.temp.BaseTypeUtil;
@@ -67,6 +70,8 @@
private boolean haveToCloseFOS = false;
private File propertiesFile = null;
private Component owner;
+ private Cipher encryptCipher = null;
+ private Cipher decryptCipher = null;
/**
* Creates a new application properties instance.
@@ -118,7 +123,61 @@
public void setAutoSave(boolean autoSave) {
this.autoSave = autoSave;
}
+
+ /**
+ * Returns the {@link Cipher} used to encrypt property values.
+ */
+ public Cipher getEncrytionCipher() {
+ return encryptCipher;
+ }
+
+ /**
+ * Returns the {@link Cipher} used to decrypt property values.
+ */
+ public Cipher getDecrytionCipher() {
+ return decryptCipher;
+ }
+
+ /**
+ * Sets ciphers used to decrypt and encrypt property values.
+ * @param encryptCipher cipher to encrypt
+ * @param decyptCiper cipher to decrypt
+ * @see #setEncrypted(Object, Object)
+ * @see #getStringDecrypted(Object, String...)
+ */
+ public void setCipher(Cipher encryptCipher, Cipher decyptCiper) {
+ this.decryptCipher = decyptCiper;
+ this.encryptCipher = encryptCipher;
+ }
+ /**
+ * Sets default DES ciphers used to decrypt and encrypt property values.
+ * @param cryptKey key used to encrypt/decrypt
+ * @see #setEncrypted(Object, Object)
+ * @see #getStringDecrypted(Object, String...)
+ */
+ public void setCipher(byte[] cryptKey) {
+ try {
+ setCipher(
+ CryptUtil.createDESCipher(Cipher.ENCRYPT_MODE, cryptKey),
+ CryptUtil.createDESCipher(Cipher.DECRYPT_MODE, cryptKey)
+ );
+ } catch (Exception err) {
+ throw new RuntimeException("Error creating DES Cipher",err);
+ }
+ }
+
+
+ /**
+ * Sets default DES ciphers used to decrypt and encrypt property values.
+ * @param cryptKey key used to encrypt/decrypt
+ * @see #setEncrypted(Object, Object)
+ * @see #getStringDecrypted(Object, String...)
+ */
+ public void setCipher(String cryptKey) {
+ setCipher(cryptKey.getBytes());
+ }
+
//***************************************************
//************* GETTER ******************************
//***************************************************
@@ -177,6 +236,24 @@
return get(key,String.class,defaultValue[0]);
}
+ /**
+ * Returns a property value which was stored encrypted in the map.
+ * @param key properties key
+ * @param defaultValueDecrypted default value (already decrypted!)
+ * returned if no value is found for the key
+ */
+ public String getStringDecrypted(KEYS key, String... defaultValueDecrypted) {
+ if ( encryptCipher == null || decryptCipher == null )
+ throw new UnsupportedOperationException("getStringDecrypted(.) can not be used before a cipher is set.");
+
+ String encryptedValue = getString(key);
+ if ( encryptedValue == null )
+ return defaultValueDecrypted.length > 0 ? defaultValueDecrypted[0] : null;
+ byte[] encryptedBytes = CryptUtil.convertWritableStringToEncryptedBytes(encryptedValue);
+ String decryptedValue = CryptUtil.decryptString(encryptedBytes, getDecrytionCipher());
+ return decryptedValue;
+ }
+
public Character getChar(KEYS key, Character... defaultValue) {
if ( defaultValue.length == 0 )
return get(key,Character.class);
@@ -195,7 +272,45 @@
if ( getAutoSave() )
store();
}
-
+
+ /**
+ * Set a value in the underlying {@link Properties}. The value
+ * is encrypted by the encryption {@link Cipher}.
+ * @see #setCipher(Cipher, Cipher)
+ * @see #setCipher(byte[])
+ * @see #setCipher(String)
+ */
+ public void setEncrypted(KEYS key, Object clearValue) {
+ if ( encryptCipher == null || decryptCipher == null )
+ throw new UnsupportedOperationException("setEncrypted(.) can not be used before a cipher is set.");
+ // NULL can not be encrypted
+ if ( clearValue == null ) {
+ LOGGER.warn("NULL value for key '"+key+"' is stored not-encrypt!");
+ set(key,clearValue);
+ return;
+ }
+ // convert Byte[] to byte[]
+ if ( clearValue instanceof Byte[] ) {
+ Byte[] b = (Byte[])clearValue;
+ clearValue = new byte[b.length];
+ for (int i=0; i<b.length; i++)
+ ((byte[])clearValue)[i] = b[i];
+ }
+ // convert byte[] to String; all others according to
+ // the toString() method
+ if ( clearValue instanceof byte[] )
+ clearValue = new String((byte[])clearValue);
+ else
+ clearValue = clearValue.toString();
+
+ byte[] encryptBytes = CryptUtil.encryptString((String)clearValue, getEncrytionCipher());
+ // Problem: encrypted bytes can not be stores as String!
+ // properties.put(key.toString(), encryptBytes) forces
+ // a crash on store() because cast to String fails!
+ // Solution: store bytes concatenated
+ set(key, CryptUtil.convertEncryptedBytesToWritableString(encryptBytes));
+ }
+
/////////////////////////////////////////////////////
/////////////// Property storage //////////////////
/////////////////////////////////////////////////////
More information about the Schmitzm-commits
mailing list