001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    package org.apache.geronimo.util;
019    
020    import java.io.ByteArrayOutputStream;
021    import java.io.ObjectOutputStream;
022    import java.io.Serializable;
023    import java.io.ObjectInputStream;
024    import java.io.ByteArrayInputStream;
025    import javax.crypto.spec.SecretKeySpec;
026    import javax.crypto.Cipher;
027    import javax.crypto.SealedObject;
028    import org.apache.geronimo.util.encoders.Base64;
029    import org.apache.commons.logging.Log;
030    import org.apache.commons.logging.LogFactory;
031    
032    /**
033     * This class protects some value BY ENCRYPTING WITH A KNOWN KEY.  That is
034     * to say, it's only safe against anyone who can't read the source code.
035     * So the main idea is to protect against casual observers.
036     *
037     * If someone has a better idea for how to implement encryption with a
038     * non-obvious key that the user isn't likely to change during the normal
039     * course of working with the server, I'd be happy to hear it.  (But I
040     * assume the SSL keystore is likely to be changed, which would result
041     * in losing all the "encrypted" data.
042     *
043     * @version $Rev: 470572 $ $Date: 2006-11-02 14:36:56 -0800 (Thu, 02 Nov 2006) $
044     */
045    public class SimpleEncryption {
046        private final static Log log = LogFactory.getLog(SimpleEncryption.class);
047        private final static SecretKeySpec SECRET_KEY = new SecretKeySpec(new byte[]{(byte)-45,(byte)-15,(byte)100,(byte)-34,(byte)70,(byte)83,(byte)75,(byte)-100,(byte)-75,(byte)61,(byte)26,(byte)114,(byte)-20,(byte)-58,(byte)114,(byte)77}, "AES");
048    
049    
050        /**
051         * Gets a String which contains the Base64-encoded form of the source,
052         * encrypted with the known key.
053         */
054        public static String encrypt(Serializable source) {
055            try {
056                Cipher c = Cipher.getInstance("AES");
057                c.init(Cipher.ENCRYPT_MODE, SECRET_KEY);
058                SealedObject so = new SealedObject(source, c);
059                ByteArrayOutputStream store = new ByteArrayOutputStream();
060                ObjectOutputStream out = new ObjectOutputStream(store);
061                out.writeObject(so);
062                out.close();
063                byte[] data = store.toByteArray();
064                byte[] textData = Base64.encode(data);
065                return new String(textData, "US-ASCII");
066            } catch (Exception e) {
067                log.error("Unable to encrypt", e);
068                return null;
069            }
070        }
071    
072        /**
073         * Given a String which is the Base64-encoded encrypted data, retrieve
074         * the original Object.
075         */
076        public static Object decrypt(String source) {
077            try {
078                byte[] data = Base64.decode(source);
079                Cipher c = Cipher.getInstance("AES");
080                c.init(Cipher.DECRYPT_MODE, SECRET_KEY);
081                ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(data));
082                SealedObject so = (SealedObject) in.readObject();
083                return so.getObject(c);
084            } catch (Exception e) {
085                log.error("Unable to decrypt", e);
086                return null;
087            }
088        }
089    }