001: /*
002: * Copyright 2006-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.opensource.org/licenses/ecl1.php
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.kuali.core.service.impl;
017:
018: import java.io.UnsupportedEncodingException;
019: import java.security.GeneralSecurityException;
020: import java.security.MessageDigest;
021:
022: import javax.crypto.Cipher;
023: import javax.crypto.KeyGenerator;
024: import javax.crypto.SecretKey;
025: import javax.crypto.SecretKeyFactory;
026: import javax.crypto.spec.DESKeySpec;
027:
028: import org.apache.commons.codec.binary.Base64;
029: import org.apache.commons.lang.StringUtils;
030: import org.kuali.core.service.Demonstration;
031: import org.kuali.core.service.EncryptionService;
032:
033: /**
034: * Implementation of encryption service for demonstration.
035: *
036: *
037: */
038: public class DemonstrationGradeEncryptionServiceImpl implements
039: EncryptionService, Demonstration {
040: public final static String ALGORITHM = "DES/ECB/PKCS5Padding";
041: public final static String HASH_ALGORITHM = "SHA";
042:
043: private transient SecretKey desKey;
044:
045: public DemonstrationGradeEncryptionServiceImpl() throws Exception {
046: if (desKey != null) {
047: throw new RuntimeException(
048: "The secret key must be kept secret. Storing it in the Java source code is a really bad idea.");
049: }
050: }
051:
052: /**
053: * @see edu.iu.uis.eden.security.EncryptionService#isEnabled()
054: */
055: public boolean isEnabled() {
056: return true;
057: }
058:
059: public String encrypt(Object valueToHide)
060: throws GeneralSecurityException {
061: if (valueToHide == null) {
062: return "";
063: }
064:
065: // Initialize the cipher for encryption
066: Cipher cipher = Cipher.getInstance(ALGORITHM);
067: cipher.init(Cipher.ENCRYPT_MODE, desKey);
068:
069: // Our cleartext
070: byte[] cleartext = valueToHide.toString().getBytes();
071:
072: // Encrypt the cleartext
073: byte[] ciphertext = cipher.doFinal(cleartext);
074:
075: return new String(Base64.encodeBase64(ciphertext));
076:
077: }
078:
079: public String decrypt(String ciphertext)
080: throws GeneralSecurityException {
081: if (StringUtils.isBlank(ciphertext)) {
082: return "";
083: }
084:
085: // Initialize the same cipher for decryption
086: Cipher cipher = Cipher.getInstance(ALGORITHM);
087: cipher.init(Cipher.DECRYPT_MODE, desKey);
088:
089: // un-Base64 encode the encrypted data
090: byte[] encryptedData = Base64.decodeBase64(ciphertext
091: .getBytes());
092:
093: // Decrypt the ciphertext
094: byte[] cleartext1 = cipher.doFinal(encryptedData);
095: return new String(cleartext1);
096: }
097:
098: /**
099: *
100: * This method generates keys. This method is implementation specific and should not be present in any general purpose interface
101: * extracted from this class.
102: *
103: * @return
104: * @throws Exception
105: */
106: public String generateEncodedKey() throws Exception {
107: Cipher cipher;
108: KeyGenerator keygen = KeyGenerator.getInstance("DES");
109: SecretKey desKey = keygen.generateKey();
110:
111: // Create the cipher
112: cipher = Cipher.getInstance(ALGORITHM);
113: cipher.init((Cipher.WRAP_MODE), desKey);
114:
115: SecretKeyFactory desFactory = SecretKeyFactory
116: .getInstance("DES");
117: DESKeySpec desSpec = (DESKeySpec) desFactory.getKeySpec(desKey,
118: javax.crypto.spec.DESKeySpec.class);
119: byte[] rawDesKey = desSpec.getKey();
120:
121: return new String(Base64.encodeBase64(rawDesKey));
122: }
123:
124: private SecretKey unwrapEncodedKey(String key) throws Exception {
125: Cipher cipher;
126: KeyGenerator keygen = KeyGenerator.getInstance("DES");
127: SecretKey desKey = keygen.generateKey();
128:
129: // Create the cipher
130: cipher = Cipher.getInstance(ALGORITHM);
131: cipher.init((Cipher.UNWRAP_MODE), desKey);
132:
133: byte[] bytes = Base64.decodeBase64(key.getBytes());
134:
135: SecretKeyFactory desFactory = SecretKeyFactory
136: .getInstance("DES");
137:
138: DESKeySpec keyspec = new DESKeySpec(bytes);
139: SecretKey k = desFactory.generateSecret(keyspec);
140:
141: return k;
142:
143: }
144:
145: /**
146: * Sets the secretKey attribute value.
147: *
148: * @param secretKey The secretKey to set.
149: * @throws Exception
150: */
151: public void setSecretKey(String secretKey) throws Exception {
152: desKey = this .unwrapEncodedKey(secretKey);
153: // Create the cipher
154: Cipher cipher = Cipher.getInstance(ALGORITHM);
155: cipher.init((Cipher.WRAP_MODE), desKey);
156: }
157:
158: /** Hash the value by converting to a string, running the hash algorithm, and then base64'ng the results.
159: * Returns a blank string if any problems occur or the input value is null or empty.
160: *
161: * @see org.kuali.core.service.EncryptionService#hash(java.lang.Object)
162: */
163: public String hash(Object valueToHide)
164: throws GeneralSecurityException {
165: if (valueToHide == null
166: || StringUtils.isEmpty(valueToHide.toString())) {
167: return "";
168: }
169: try {
170: MessageDigest md = MessageDigest
171: .getInstance(HASH_ALGORITHM);
172: return new String(Base64.encodeBase64(md.digest(valueToHide
173: .toString().getBytes("UTF-8"))), "UTF-8");
174: } catch (UnsupportedEncodingException ex) {
175: // should never happen
176: }
177: return "";
178: }
179:
180: }
|