Sunday, May 19, 2013

OIM 11g R1: Getting OIM User Decrypted Password

Version: Oracle Identity Manager 11g R1
Description:
If you look at the OIM.USR table, you'll notice that the password column is encrypted. There are several ways to get the password decrypted. I'll be showing you how to get the decrypted password by querying from the OIM database using the tcDataBaseClient. This requires you to set the client handle with the OIMClient object. The user who is logged in for the OIMClient needs to be an End-User Administrator in order to use the tcDatabaseClient. The “Design Console Access” attribute on the OIM User Profile determines whether a user is an End-User or an End-User Administrator. Below is a java application to get all the OIM users' passwords in plain text.  Note: You can also query the OIM.PCQ table to get users' challenge questions and answers.

import Thor.API.Security.XLClientSecurityAssociation;
import com.thortech.xl.dataaccess.tcDataBaseClient;
import com.thortech.xl.dataaccess.tcDataProvider;
import com.thortech.xl.dataaccess.tcDataSet;
import com.thortech.xl.dataaccess.tcDataSetException;
import java.util.Hashtable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.security.auth.login.LoginException;
import oracle.iam.platform.OIMClient;

/**
 * This class gets the OIM Client and uses that to establish a
 * connection to the OIM Schema. You can query the USR table and
 * get the password in plain text. 
 * NOTE: The administrator credential must be used for the OIM Client. 
 */
public class DecryptedOIMPassword 
{
    public static void main(String[] args)
    {
        tcDataProvider dbProvider = null;
        OIMClient oimClient = null;

        try 
        {
            String ctxFactory = "weblogic.jndi.WLInitialContextFactory"; //WebLogic Context 
            String oimServerURL = "t3://localhost:14000"; //OIM URL
            String authwlConfigPath = "resources/config/authwl.conf"; //Path to login configuration
            String username = "xelsysadm"; //OIM Administrator 
            String password = "Password1"; //Administrator Password

            System.setProperty("java.security.auth.login.config", authwlConfigPath); //set the login configuration
            Hashtable<string,string> env = new Hashtable<string,string>(); //use to store OIM environment properties
            env.put(OIMClient.JAVA_NAMING_FACTORY_INITIAL, ctxFactory);
            env.put(OIMClient.JAVA_NAMING_PROVIDER_URL, oimServerURL);
            oimClient = new OIMClient(env);
            oimClient.login(username, password.toCharArray()); //login to OIM

            XLClientSecurityAssociation.setClientHandle(oimClient);//Needed for database client
            dbProvider = new tcDataBaseClient(); //Connection to OIM Schema
            tcDataSet dataSet = new tcDataSet(); //Stores the result set of an executed query
            String query = "SELECT * FROM USR"; //Query Users table
            //String query = "SELECT * FROM PCQ"; //Query Users Challenge Question
            dataSet.setQuery(dbProvider, query); //Set query and database provider
            dataSet.executeQuery(); //execute query and store results into dataSet object
            int records = dataSet.getTotalRowCount(); //Get total records from result set

            for(int i = 0; i < records; i++)
            {
                dataSet.goToRow(i); //move pointer to next record
                String plainTextPassword = dataSet.getString("USR_PASSWORD");
                String userLogin = dataSet.getString("USR_LOGIN");
                String userStatus = dataSet.getString("USR_STATUS");
                System.out.printf("User Login: %s\nStatus: %s\nPassword: %s\n\n", userLogin, userStatus, plainTextPassword);  

                //Getting user challenge questions and answers
                //String usrKey = dataSet.getString("USR_KEY");
                //String question = dataSet.getString("PCQ_QUESTION");
                //String answer = dataSet.getString("PCQ_ANSWER");
                //System.out.printf("USR_KEY: %s\nQuestion: %s\nAnswer: %s\n", usrKey, question, answer);
            }
        } 

        catch (tcDataSetException ex) 
        { 
            Logger.getLogger(DecryptedOIMPassword.class.getName()).log(Level.SEVERE, null, ex);
        }

        catch (LoginException ex) 
        {
            Logger.getLogger(DecryptedOIMPassword.class.getName()).log(Level.SEVERE, null, ex);
        }

        finally
        {
            //close connections
            try{dbProvider.close();} catch(Exception e){}
            try{XLClientSecurityAssociation.clearThreadLoginSession();} catch(Exception e){}
            try{oimClient.logout();} catch(Exception e) {}
        }     
    }//end main method   
}//end class

10 comments:

  1. Hello,

    instead of password in clear, getting *******. Can you help?

    Best,
    Marek.

    ReplyDelete
  2. What algorithm OIM R1 uses for password encryption in USR table?
    is there any document that specifies that?

    ReplyDelete
  3. This code works prior to 11gR2 PS2.

    ReplyDelete
  4. Any-workaround for 11gR2 PS2

    ReplyDelete
  5. BS

    dataSet.getString("USR_PASSWORD") returns encrypted string

    ReplyDelete
  6. Has anyone successfully decrypted password using a remote OIMClient?
    I am trying to decrypt passwords using the following OIM APIs:

    String password = com.thortech.xl.crypto.tcCryptoUtil.decrypt(encryptedPassword, "DBSecretKey");

    I followed "http://oraclestack.blogspot.com/2013/06/post-process-eventhandler-example.html". This works when the code is executed within OIM, but not with a remote OIMClient.

    ReplyDelete
  7. I used the above code to successfully decrypt passwords stored in the USR table. This was for OIM 11.1.1.5.X. Via a remote client (java POJO). It seems very scary just how simple it is to decrypt the passwords. All you need is valid credentials for someone who has the System Admin role and the above code.

    ReplyDelete
  8. Does this code valid for 11gR2 PS3 ?

    ReplyDelete
  9. I tried to decrypt the challenge question. The code is executed within OIM. I received the following error and I know the real path of jps-config.xml is in config/fmwconfig/jps-config.xml. However the code is looking for jps-config.xml in config/jps-config.xml. Please help me with the error below:
    SEVERE: Class/Method: tcDefaultDBEncryptionImpl/initKeyStore encounter some problems: ./config/jps-config.xml (No such file or directory)
    oracle.security.jps.config.JpsConfigurationException: ./config/jps-config.xml (No such file or directory)
    at oracle.security.jps.internal.config.xml.XmlConfigurationFactory.initDefaultConfiguration(XmlConfigurationFactory.java:439)
    at oracle.security.jps.internal.config.xml.XmlConfigurationFactory.getDefaultConfiguration(XmlConfigurationFactory.java:338)
    at oracle.security.jps.internal.config.xml.XmlConfigurationFactory.getConfiguration(XmlConfigurationFactory.java:160)
    at oracle.security.jps.internal.core.runtime.JpsContextFactoryImpl.(JpsContextFactoryImpl.java:112)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at java.lang.Class.newInstance0(Class.java:361)
    at java.lang.Class.newInstance(Class.java:314)
    at oracle.security.jps.util.JpsUtil.newInstance(JpsUtil.java:190)
    at oracle.security.jps.JpsContextFactory$1.run(JpsContextFactory.java:76)
    at oracle.security.jps.JpsContextFactory$1.run(JpsContextFactory.java:73)
    at oracle.security.jps.JpsContextFactory.getContextFactory(JpsContextFactory.java:72)
    at oracle.iam.platform.utils.config.CSFCredentialProvider.getPassword(CSFCredentialProvider.java:74)
    at oracle.iam.platform.utils.config.standalone.StandAloneCryptoConfig.getPassword(StandAloneCryptoConfig.java:76)
    at com.thortech.xl.crypto.tcDefaultDBEncryptionImpl.initKeyStore(tcDefaultDBEncryptionImpl.java:67)
    at com.thortech.xl.crypto.tcDefaultDBEncryptionImpl.getCipher(tcDefaultDBEncryptionImpl.java:99)
    at com.thortech.xl.crypto.tcDefaultDBEncryptionImpl.decrypt(tcDefaultDBEncryptionImpl.java:218)
    at com.thortech.xl.crypto.tcCryptoUtil.decrypt(tcCryptoUtil.java:122)
    at com.thortech.xl.crypto.tcCryptoUtil.decrypt(tcCryptoUtil.java:163)
    at ChallengeAnswerDecryptForThao.main(ChallengeAnswerDecryptForThao.java:92)
    Caused by: java.io.FileNotFoundException: ./config/jps-config.xml (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.(FileInputStream.java:120)
    at oracle.security.jps.internal.common.util.XmlSchemaValidationUtil.doValidation(XmlSchemaValidationUtil.java:101)
    at oracle.security.jps.internal.config.xml.XmlConfigurationFactory.initDefaultConfiguration(XmlConfigurationFactory.java:418)
    ... 21 more
    com.thortech.xl.crypto.tcCryptoException: ./config/jps-config.xml (No such file or directory)
    at com.thortech.xl.crypto.tcDefaultDBEncryptionImpl.initKeyStore(tcDefaultDBEncryptionImpl.java:79)
    at com.thortech.xl.crypto.tcDefaultDBEncryptionImpl.getCipher(tcDefaultDBEncryptionImpl.java:99)
    at com.thortech.xl.crypto.tcDefaultDBEncryptionImpl.decrypt(tcDefaultDBEncryptionImpl.java:218)
    at com.thortech.xl.crypto.tcCryptoUtil.decrypt(tcCryptoUtil.java:122)
    at com.thortech.xl.crypto.tcCryptoUtil.decrypt(tcCryptoUtil.java:163)
    at ChallengeAnswerDecryptForThao.main(ChallengeAnswerDecryptForThao.java:92)
    Caused by: oracle.security.jps.config.JpsConfigurationException: ./config/jps-config.xml (No such file or directory)
    at oracle.security.jps.internal.config.xml.XmlConfigurationFactory.initDefaultConfiguration(XmlConfigurationFactory.java:439)
    Thank you!

    ReplyDelete
  10. thanks for the code.. but plz correct that line

    Hashtable env = new Hashtable(); //use to store OIM environment properties

    to

    Hashtable env = new Hashtable(); //use to store OIM environment properties

    string s is Capital.. This took 1 hr to figure it out :) chers

    Regards/Jawad Rizvi

    ReplyDelete