1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.geronimo.crypto; 18 19 import java.util.Collections; 20 import java.util.HashMap; 21 import java.util.Map; 22 import java.io.Serializable; 23 24 /** 25 * A static class that uses registered Encryption instances to encypt and decrypt objects, typically strings. 26 * The encrypted strings are preceded by the name of the Encryption object, such as {Simple}, followed by the base64 27 * encoded encrypted bytes. 28 * 29 * Any number of Encryption instances can be registered but only the first to be explicitly registered will be used. 30 * However, when decrypting the Encryption instance is looked up from the name prefix so may be any registered Encryption instance. 31 * Furthermore, encrypt and decrypt are idempotent. Calling encrypt on a string encrypted with a registered Encryption that is not 32 * the one in use will decrypt the string and re-encrypt it with the one in use. This can be useful when changing Encryption. 33 * 34 * The default Encryption instance (that does not need to be registered) is SimpleEncryption which uses a fixed key hardcoded into 35 * the Encryption class itself. Thus it is useful only to hide information from those who don't read code. On the other hand 36 * you can't lose the key and make your server permanently unusable. 37 * 38 * n.b. calling these methods idempotent is a slight exageration as this would apply only if all arguments and return values are Strings. 39 * 40 * @version $Rev: 617737 $ $Date: 2008-02-01 17:39:58 -0800 (Fri, 01 Feb 2008) $ 41 */ 42 public class EncryptionManager { 43 44 private static final Map<String, Encryption> ENCRYPTORS = Collections.synchronizedMap(new HashMap<String, Encryption>()); 45 private final static String SIMPLE_ENCRYPTION_PREFIX = "{Simple}"; 46 47 static { 48 ENCRYPTORS.put(SIMPLE_ENCRYPTION_PREFIX, SimpleEncryption.INSTANCE); 49 //login properties files used to have this 50 ENCRYPTORS.put("{Standard}", SimpleEncryption.INSTANCE); 51 } 52 53 private static String encryptionPrefix = SIMPLE_ENCRYPTION_PREFIX; 54 55 /** 56 * Encryption instances should call this to register themselves. 57 * 58 * @param prefix id in form {name} for the Encryption instance 59 * @param encryption Encryption instance to do the work. 60 */ 61 public synchronized static void setEncryptionPrefix(String prefix, Encryption encryption) { 62 if (SIMPLE_ENCRYPTION_PREFIX.equals(encryptionPrefix)) { 63 encryptionPrefix = prefix; 64 } 65 ENCRYPTORS.put(prefix, encryption); 66 } 67 68 /** 69 * Idempotent method that outputs string starting with the active registered encryption prefix followed by 70 * the output of the registered Encryption instance. If called with a string encrypted by another 71 * registered Encryption it will re-encrypt with the active Encryption instance. 72 * @param source Serializable object to encrypt, usually a password string or an already encrypted string. 73 * @return the name of the registered Encryption followed by its output. 74 */ 75 public static String encrypt(Serializable source) { 76 if (source instanceof String) { 77 String sourceString = (String) source; 78 if (sourceString.startsWith(encryptionPrefix)) { 79 return (String) source; 80 } else if (sourceString.startsWith("{")) { 81 source = decrypt(sourceString); 82 } 83 } 84 Encryption encryption = ENCRYPTORS.get(encryptionPrefix); 85 return encryptionPrefix + encryption.encrypt(source); 86 } 87 88 /** 89 * Idempotent method that given a String starting with a registered Encryption name will remove the 90 * name prefix and return the result of applying the Encryption to the suffix. If no registered Encryption 91 * name matches the start of the string the input will be returned. 92 * @param source String that is possibly the output of calling encrypt, consisting of a Encryption name followed by its encrypt output. 93 * @return the result of applying the Encryption.decrypt method to the input suffix after identifying the Encryption from the prefix, or the 94 * input if no Encryption name matches. 95 */ 96 public static Serializable decrypt(String source) { 97 String prefix = null; 98 Encryption encryption = null; 99 synchronized (ENCRYPTORS) { 100 for (Map.Entry<String, Encryption> entry : ENCRYPTORS.entrySet()) { 101 prefix = entry.getKey(); 102 if (source.startsWith(prefix)) { 103 encryption = entry.getValue(); 104 break; 105 } 106 } 107 } 108 if (encryption != null) { 109 return encryption.decrypt(source.substring(prefix.length())); 110 } 111 return source; 112 } 113 }