001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with 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,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.entity.util;
019:
020: import java.security.NoSuchAlgorithmException;
021: import java.util.HashMap;
022: import java.util.Map;
023: import java.util.Random;
024:
025: import javax.crypto.SecretKey;
026: import javax.transaction.Transaction;
027:
028: import org.ofbiz.base.crypto.DesCrypt;
029: import org.ofbiz.base.crypto.HashCrypt;
030: import org.ofbiz.base.util.Debug;
031: import org.ofbiz.base.util.GeneralException;
032: import org.ofbiz.base.util.StringUtil;
033: import org.ofbiz.base.util.UtilMisc;
034: import org.ofbiz.base.util.UtilObject;
035: import org.ofbiz.entity.EntityCryptoException;
036: import org.ofbiz.entity.GenericDelegator;
037: import org.ofbiz.entity.GenericEntityException;
038: import org.ofbiz.entity.GenericValue;
039: import org.ofbiz.entity.transaction.GenericTransactionException;
040: import org.ofbiz.entity.transaction.TransactionUtil;
041:
042: public class EntityCrypto {
043:
044: public static final String module = EntityCrypto.class.getName();
045:
046: protected GenericDelegator delegator = null;
047: protected Map keyMap = null;
048:
049: protected EntityCrypto() {
050: }
051:
052: public EntityCrypto(GenericDelegator delegator) {
053: this .delegator = delegator;
054: this .keyMap = new HashMap();
055:
056: // check the key table and make sure there
057: // make sure there are some dummy keys
058: synchronized (EntityCrypto.class) {
059: try {
060: long size = delegator.findCountByAnd("EntityKeyStore",
061: null);
062: if (size == 0) {
063: for (int i = 0; i < 20; i++) {
064: String randomName = this .getRandomString();
065: this .getKeyFromStore(randomName);
066: }
067: }
068: } catch (GenericEntityException e) {
069: Debug.logError(e, module);
070: }
071: }
072: }
073:
074: /** Encrypts a String into an encrypted hex encoded byte array */
075: public String encrypt(String keyName, Object obj)
076: throws EntityCryptoException {
077: try {
078: return StringUtil.toHexString(DesCrypt.encrypt(this
079: .getKey(keyName), UtilObject.getBytes(obj)));
080: } catch (GeneralException e) {
081: throw new EntityCryptoException(e);
082: }
083: }
084:
085: /** Decrypts a hex encoded byte array into a String */
086: public Object decrypt(String keyName, String str)
087: throws EntityCryptoException {
088: try {
089: return UtilObject.getObject(DesCrypt.decrypt(this
090: .getKey(keyName), StringUtil.fromHexString(str)));
091: } catch (GeneralException e) {
092: throw new EntityCryptoException(e);
093: }
094: }
095:
096: protected SecretKey getKey(String name)
097: throws EntityCryptoException {
098: SecretKey key = (SecretKey) keyMap.get(name);
099: if (key == null) {
100: synchronized (this ) {
101: String keyName = HashCrypt.getDigestHash(name);
102: key = this .getKeyFromStore(keyName);
103: keyMap.put(name, key);
104: }
105: }
106: return key;
107: }
108:
109: protected SecretKey getKeyFromStore(String keyName)
110: throws EntityCryptoException {
111: GenericValue keyValue = null;
112: try {
113: keyValue = delegator.findByPrimaryKey("EntityKeyStore",
114: UtilMisc.toMap("keyName", keyName));
115: } catch (GenericEntityException e) {
116: throw new EntityCryptoException(e);
117: }
118: if (keyValue == null || keyValue.get("keyText") == null) {
119: SecretKey key = null;
120: try {
121: key = DesCrypt.generateKey();
122: } catch (NoSuchAlgorithmException e) {
123: throw new EntityCryptoException(e);
124: }
125: GenericValue newValue = delegator.makeValue(
126: "EntityKeyStore", null);
127: newValue.set("keyText", StringUtil.toHexString(key
128: .getEncoded()));
129: newValue.set("keyName", keyName);
130:
131: Transaction parentTransaction = null;
132: boolean beganTrans = false;
133: try {
134: beganTrans = TransactionUtil.begin();
135: } catch (GenericTransactionException e) {
136: throw new EntityCryptoException(e);
137: }
138:
139: if (!beganTrans) {
140: try {
141: parentTransaction = TransactionUtil.suspend();
142: } catch (GenericTransactionException e) {
143: throw new EntityCryptoException(e);
144: }
145:
146: // now start a new transaction
147: try {
148: beganTrans = TransactionUtil.begin();
149: } catch (GenericTransactionException e) {
150: throw new EntityCryptoException(e);
151: }
152: }
153:
154: try {
155: delegator.create(newValue);
156: } catch (GenericEntityException e) {
157: try {
158: TransactionUtil.rollback(beganTrans,
159: "Error creating encrypted value", e);
160: } catch (GenericTransactionException e1) {
161: Debug.logError(e1,
162: "Could not rollback transaction", module);
163: }
164: throw new EntityCryptoException(e);
165: } finally {
166: try {
167: TransactionUtil.commit(beganTrans);
168: } catch (GenericTransactionException e) {
169: throw new EntityCryptoException(e);
170: }
171: // resume the parent transaction
172: if (parentTransaction != null) {
173: try {
174: TransactionUtil.resume(parentTransaction);
175: } catch (GenericTransactionException e) {
176: throw new EntityCryptoException(e);
177: }
178: }
179: }
180:
181: return key;
182: } else {
183: byte[] keyBytes = StringUtil.fromHexString(keyValue
184: .getString("keyText"));
185: try {
186: return DesCrypt.getDesKey(keyBytes);
187: } catch (GeneralException e) {
188: throw new EntityCryptoException(e);
189: }
190: }
191: }
192:
193: protected String getRandomString() {
194: Random rand = new Random();
195: byte[] randomBytes = new byte[24];
196: rand.nextBytes(randomBytes);
197: return StringUtil.toHexString(randomBytes);
198: }
199: }
|