package it.valueteam.securityutility; import java.io.*; import java.security.*; import java.util.*; import javax.crypto.*; import javax.crypto.spec.DESedeKeySpec; import sun.misc.*; /** *
Title:
*Description:
*Copyright: Copyright (c) 2005
*Company:
* @author Paolo Marini * @version 1.0 */ public class CryptoUtility { public static final String TRIPLE_DES_CHIPER = "DESede/ECB/PKCS5Padding"; public static final String TRIPLE_DES_PREFIX = "{3DES}"; public static final String TRIPLE_DES_KEY = "DESede"; public static final int TRIPLE_DES_KEY_SIZE = 168; public static final String KEY_MISSING = "Symmetric Key Missing"; public static final String MEMORY_ADDRESS = "INDIRIZZO_KEY"; public static final String FLAG_SHARED_KEY = "USE_CRYPTO_SHARED"; public static final String FILE_KEY = "PATH_KEY"; public static final String INDIRIZZO_DINAMICO = "USE_DYNAMIC_ADDRESS"; public static final int INDIRIZZO_STATICO = 5625; private Key chiave3DES = null; private static CryptoUtility onlyInstance = null; /** * Costruttore * @throws Exception */ private CryptoUtility() throws Exception{ String fileChiave=null; int indirizzo; String confFile = System.getProperty("security_conf_file"); IniFile iniFile = new IniFile(confFile); Properties p = iniFile.getSection("main.properties"); if("true".equalsIgnoreCase(p.getProperty(FLAG_SHARED_KEY))) { indirizzo = "true".equalsIgnoreCase(p.getProperty(INDIRIZZO_DINAMICO))? Integer.parseInt(p.getProperty(MEMORY_ADDRESS)): INDIRIZZO_STATICO; try { readKey(indirizzo); } catch (Exception ex) { System.out.println("Impossibile caricare la chiave dalla ram: verificare che la chiave sia presente."); throw new Exception("Impossibile caricare la chiave dalla ram."); } } else { fileChiave = (String) p.get(FILE_KEY); loadKey(fileChiave); } } /** * Utilizzato da applicazioni che inizializzano esplicitamente l'api * di cifratura con init(). Il Properties č letto autonomamente prima dell'init. * @param config Le properties contenute nel file security.properties. * @throws Exception */ private CryptoUtility(Properties config) throws Exception { String fileChiave = null; int indirizzo; if("true".equalsIgnoreCase(config.getProperty(FLAG_SHARED_KEY))) { indirizzo = "true".equalsIgnoreCase(config.getProperty(INDIRIZZO_DINAMICO))? Integer.parseInt(config.getProperty(MEMORY_ADDRESS)): INDIRIZZO_STATICO; try { readKey(indirizzo); } catch (Exception ex) { System.out.println("Impossibile caricare la chiave dalla ram: verificare che la chiave sia presente."); throw new Exception("Impossibile caricare la chiave dalla ram."); } } else { fileChiave = (String) config.get(FILE_KEY); loadKey(fileChiave); } } /** * Inizializzazione del framework di security * @param fileChiave String * @throws Exception * @return CryptoUtility */ public static CryptoUtility getInstance() throws Exception{ if (onlyInstance==null) { synchronized(CryptoUtility.class) { if (onlyInstance==null) { onlyInstance = new CryptoUtility(); } } } return onlyInstance; } /** * Utilizzato per inizializzare la classe prima delle operazioni di cifratura. * @param secConfig Le properties del file security.properties * @throws Exception */ public static void init(Properties secConfig) throws Exception{ onlyInstance = new CryptoUtility(secConfig); } /** * carica la chiave simmetrica di cifratura/decifratura * @param fileChiave String * @throws Exception */ private void loadKey(String fileChiave) throws Exception{ ObjectInputStream in = null; try { in = new ObjectInputStream(new FileInputStream(fileChiave)); chiave3DES = (Key)in.readObject(); } finally { if(in!=null) { try { in.close(); } catch (IOException ex) { ex.printStackTrace(); } } } } /** * Legge la chiave (raw byte) dalla shared memory attraverso il bridge JNI * @param indirizzo L'indirizzo della chiave nella memoria * @throws Exception */ private void readKey(int indirizzo) throws Exception{ DESedeKeySpec spec = null; KeyJNIBridge bridge = new KeyJNIBridge(); spec = new DESedeKeySpec(bridge.readKey(indirizzo)); chiave3DES = SecretKeyFactory.getInstance(CryptoUtility.TRIPLE_DES_KEY).generateSecret(spec); } /** * funzione di criptazione * @param value String * @throws Exception * @return String */ public String cripta3DES(String value) throws Exception{ byte[] res = null; Cipher cipher = Cipher.getInstance(TRIPLE_DES_CHIPER); cipher.init(Cipher.ENCRYPT_MODE, chiave3DES); byte[] val = value.getBytes(); res = new byte[cipher.getOutputSize(val.length)]; int size = cipher.update(val, 0, val.length, res, 0); size += cipher.doFinal(res,size); return toString(res,res.length); } /** * funzione di decriptazione * @param value String * @throws Exception * @return String */ public String decripta3DES(String value) throws Exception{ Cipher cipher = Cipher.getInstance(TRIPLE_DES_CHIPER); cipher.init(Cipher.DECRYPT_MODE, chiave3DES); return new String(cipher.doFinal(toByteArray(value))); } /** * funzione di decriptazione che automaticamte elimina il prefisso 3DES * @param value String * @throws Exception * @return String */ public String decripta3DESWithPrefix(String value) throws Exception{ return decripta3DES(value.substring(TRIPLE_DES_PREFIX.length())); } private static final String toString(byte[] bytes,int length) { BASE64Encoder encoder = new BASE64Encoder(); String base64 = encoder.encode(bytes); return base64; } private static final byte[] toByteArray(String string) throws Exception{ BASE64Decoder decoder = new BASE64Decoder(); byte[] raw = decoder.decodeBuffer(string); return raw; } /** * decripta un inputstream ritornandone un inputstream uno con tutte le key in chiaro * @param filename String * @throws Exception * @return InputStream */ public InputStream getCleanFile(InputStream in) throws Exception { ByteArrayInputStream bin = null; String read = null; BufferedReader input = new BufferedReader(new InputStreamReader(in)); String key = null; String value = null; String cleanValue = null; StringBuffer stringOutput = new StringBuffer(); byte[] b = null; int idx = -1; while ( (read = input.readLine()) != null) { if ( (read.startsWith(";") || read.startsWith("#"))) stringOutput.append(read + "\n"); else { idx = read.indexOf("="); if (idx == -1) stringOutput.append(read + "\n"); else { cleanValue = ""; key = read.substring(0, idx); if (idx < read.length()) value = read.substring(idx + 1, read.length()); else value = ""; cleanValue = value; if ( (key.startsWith(TRIPLE_DES_PREFIX)) && value != null && value.length() > 0) { try { if (value.startsWith(TRIPLE_DES_PREFIX)) { cleanValue = decripta3DES(value.substring(TRIPLE_DES_PREFIX. length())); // System.out.println("decripta3DES:" + key); } // else // System.out.println("NOT decripta3DES:" + key); } catch (Exception ex) { System.out.println("Errore durante il decript della chiave:"+key); ex.printStackTrace(); throw ex; } } stringOutput.append(key + "=" + cleanValue + "\n"); } } } b = stringOutput.toString().getBytes(); bin = new ByteArrayInputStream(b); return bin; } /** * decripta un properties ritornandone uno con tutte le key in chiaro * @param inProperties Properties * @throws Exception * @return Properties */ public Properties getCleanProperties(Properties inProperties) throws Exception{ String key=null; String value=null; String cleanValue=null; Properties outProperties = new Properties(); if ((inProperties!=null) && (inProperties.size()!=0)) { Enumeration e = inProperties.keys(); while (e.hasMoreElements()) { key = (String) e.nextElement(); value = (String)inProperties.get(key); cleanValue = value; if ((key.startsWith(TRIPLE_DES_PREFIX)) && value!=null && value.length()>0) { try { if (value.startsWith(TRIPLE_DES_PREFIX)) { cleanValue = decripta3DES(value.substring(TRIPLE_DES_PREFIX.length())); // System.out.println("decripta3DES:"+key); } // else // System.out.println("NOT decripta3DES:"+key); } catch (Exception ex) { System.out.println("Errore durante il decript della chiave:"+key); ex.printStackTrace(); throw ex; } } outProperties.put(key,cleanValue); } } return outProperties; } /** * Chipta una pwd della proprietÓ in ingresso del relativo file * @param file String * @param key String * @param value String * @throws Exception */ public void criptaFileEntry(String file, String key, String value) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayInputStream bin = new ByteArrayInputStream(baos.toByteArray()); baos = new ByteArrayOutputStream(); PrintWriter writer = new PrintWriter(baos); BufferedReader reader = null; FileOutputStream out = null; String pwd = TRIPLE_DES_PREFIX + cripta3DES(value); try { reader = new BufferedReader(new FileReader(file)); String linea = null; while ( (linea = reader.readLine()) != null) { if (linea.startsWith(key)) { writer.println(key + "=" + pwd); } else { writer.println(linea); } } writer.close(); reader.close(); reader = null; baos.flush(); out = new FileOutputStream(file); baos.writeTo(out); out.close(); out = null; } finally { if (reader != null) { try { reader.close(); } catch (IOException ex) { } } if (out != null) { out.close(); } } } }