/* * RapidMiner * * Copyright (C) 2001-2011 by Rapid-I and the contributors * * Complete list of developers available at our web site: * * http://rapid-i.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.tools.cipher; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.logging.Level; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import com.rapidminer.RapidMiner; import com.rapidminer.tools.FileSystemService; import com.rapidminer.tools.LogService; /** * This class can be used to generate a new key and store it in the user * directory. Please note that existing keys will be overwritten * by objects of this class. That means that passwords stored with "old" * keys can no longer be decrypted. * * @author Ingo Mierswa */ public class KeyGeneratorTool { private static final String GENERATOR_TYPE = "DESede"; private static final String KEY_FILE_NAME = "cipher.key"; public static SecretKey createSecretKey() throws KeyGenerationException { KeyGenerator keyGenerator = null; try { keyGenerator = KeyGenerator.getInstance(GENERATOR_TYPE); } catch (NoSuchAlgorithmException e) { throw new KeyGenerationException("Cannot generate key, generation algorithm not known."); } keyGenerator.init(168, new SecureRandom()); // actual generation return keyGenerator.generateKey(); } public static void createAndStoreKey() throws KeyGenerationException { if (!RapidMiner.getExecutionMode().canAccessFilesystem()) { LogService.getRoot().config("Skip key generation in execution mode "+RapidMiner.getExecutionMode()); return; } // actual generation SecretKey key = createSecretKey(); File keyFile = new File(FileSystemService.getUserRapidMinerDir(), KEY_FILE_NAME); if (!keyFile.delete()) { LogService.getRoot().warning("Failed to delete old key file."); } byte[] rawKey = key.getEncoded(); try { ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(keyFile)); out.writeInt(rawKey.length); out.write(rawKey); out.close(); } catch (Exception e) { LogService.getRoot().log(Level.WARNING, "Failed to generate key: "+e, e); throw new KeyGenerationException("Cannot store key: " + e.getMessage()); } } public static Key getUserKey() throws IOException { File keyFile = new File(FileSystemService.getUserRapidMinerDir(), KEY_FILE_NAME); ObjectInputStream in = null; try { in = new ObjectInputStream(new FileInputStream(keyFile)); int length = in.readInt(); byte[] rawKey = new byte[length]; int actualLength = in.read(rawKey); if (length != actualLength) throw new IOException("Cannot read key file (unexpected length)"); return makeKey(rawKey); } catch (Exception e) { throw new IOException("Cannot retrieve key: " + e.getMessage()); } finally { if (in != null) in.close(); } } public static SecretKeySpec makeKey(byte[] rawKey) { return new SecretKeySpec(rawKey, GENERATOR_TYPE); } }