/**
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2009 Sun Microsystems Inc. All Rights Reserved
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* https://opensso.dev.java.net/public/CDDLv1.0.html or
* opensso/legal/CDDLv1.0.txt
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at opensso/legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id: JCECrypt.java,v 1.1 2009/05/05 21:24:47 veiming Exp $
*
*/
/*
* Portions Copyrighted 2011-2014 ForgeRock AS
*/
package com.sun.identity.setup;
import com.iplanet.services.util.AMEncryption;
import com.iplanet.services.util.ConfigurableKey;
import com.iplanet.services.util.JCEEncryption;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import com.sun.identity.shared.debug.Debug;
import com.sun.identity.shared.encode.Base64;
/**
* The class Crypt
provides generic methods to encryt and decrypt
* data. This class provides a pluggable architecture to encrypt and decrypt
* data, using the AMEncryption
interface class. A class that
* implements AMEncryption
must be specified via the system
* property: com.iplanet.services.security.encryptor
. If none is
* provided, the default provided by iDSAME
* com.iplanet.services.util.JCEEncryption
will be used.
*
* Additionally, it provides a method to check if the calling class has * permission to call these methods. To enable the additional security, the * property com.sun.identity.security.checkcaller must be set to true. */ public class JCECrypt { private static final String ENCRYPTOR_CLASS_PROPERTY = "com.iplanet.security.encryptor"; private static final String DEFAULT_ENCRYPTOR_CLASS = "com.iplanet.services.util.JCEEncryption"; private static final String DEFAULT_PWD = "KmhUnWR1MYWDYW4xuqdF5nbm+CXIyOVt"; private static AMEncryption encryptor; static { encryptor = createInstance(DEFAULT_PWD); } private static AMEncryption createInstance(String password) { AMEncryption instance; // Construct the encryptor class String encClass = System.getProperty(ENCRYPTOR_CLASS_PROPERTY, DEFAULT_ENCRYPTOR_CLASS); try { instance = Class.forName(encClass).asSubclass(AMEncryption.class).newInstance(); } catch (Exception e) { Debug debug = Debug.getInstance("amSDK"); debug.error("JCECrypt.createInstance Unable to get class instance: " + encClass + ", falling back to the" + " default implementation: " + DEFAULT_ENCRYPTOR_CLASS, e); instance = new JCEEncryption(); } try { ((ConfigurableKey) instance).setPassword(password); } catch (Exception e) { Debug debug = Debug.getInstance("amSDK"); if (debug != null) { debug.error( "JCECrypt.createInstance: failed to set password-based key", e); } } return instance; } private static String encode(String clearText, AMEncryption encr) { if (clearText == null || clearText.length() == 0) { return null; } // Encrypt the data byte[] encData = null; try { encData = encr.encrypt(clearText.getBytes("utf-8")); } catch (UnsupportedEncodingException uee) { Debug debug = Debug.getInstance("amSDK"); debug.error("Crypt:: utf-8 encoding is not supported"); encData = encryptor.encrypt(clearText.getBytes()); } // BASE64 encode the data String str = null; // Perf Improvement : Removed the sync block and newed up the Encoder // object for every call. Its a trade off b/w CPU and mem usage. str = Base64.encode(encData).trim(); // Serialize the data, i.e., remove \n and \r BufferedReader bufReader = new BufferedReader(new StringReader(str)); StringBuilder strClean = new StringBuilder(str.length()); String strTemp = null; try { while ((strTemp = bufReader.readLine()) != null) { strClean.append(strTemp); } } catch (IOException ioe) { Debug debug = Debug.getInstance("amSDK"); debug.error("Crypt:: Error while base64 encoding", ioe); } return (strClean.toString()); } public static String encode(String clearText) { return encode(clearText, encryptor); } private static String decode(String encoded, AMEncryption encr) { if (encoded == null || encoded.length() == 0) { return (null); } // BASE64 decode the data byte[] encData = null; // Perf Improvement : Removed the sync block and newed up the Decoder // object for every call. Its a trade off b/w CPU and mem usage. encData = Base64.decode(encoded.trim()); // Decrypt the data byte[] rawData = encr.decrypt(encData); if (rawData == null) { return (null); } // Convert to String and return String answer = null; try { answer = new String(rawData, "utf-8"); } catch (UnsupportedEncodingException uue) { Debug debug = Debug.getInstance("amSDK"); debug.error("Crypt:: Unsupported encoding UTF-8", uue); answer = new String(rawData); } return (answer); } /** * Decode an encoded string * * @param encoded * The encoded string. * @return The decoded string. */ public static String decode(String encoded) { return decode(encoded, encryptor); } }