360 lines
10 KiB
Java
360 lines
10 KiB
Java
package it.valueteam.securityutility;
|
|
|
|
import java.io.*;
|
|
import java.security.*;
|
|
import java.util.*;
|
|
import javax.crypto.*;
|
|
|
|
import javax.crypto.spec.DESedeKeySpec;
|
|
|
|
import sun.misc.*;
|
|
|
|
/**
|
|
* <p>Title: </p>
|
|
* <p>Description: </p>
|
|
* <p>Copyright: Copyright (c) 2005</p>
|
|
* <p>Company: </p>
|
|
* @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();
|
|
}
|
|
}
|
|
}
|
|
}
|