{"id":2266,"date":"2016-11-04T00:21:38","date_gmt":"2016-11-04T02:21:38","guid":{"rendered":"http:\/\/dev.dbarj.com.br\/en\/?page_id=2266"},"modified":"2020-01-17T07:02:53","modified_gmt":"2020-01-17T10:02:53","slug":"oratotp-oracle-time-based-one-time-password","status":"publish","type":"page","link":"https:\/\/dev.dbarj.com.br\/en\/oratotp-oracle-time-based-one-time-password\/","title":{"rendered":"OraTOtP ( Oracle Time-based One-time Password )"},"content":{"rendered":"<h1><strong>OraTOtP<\/strong><\/h1>\n<p><strong>OraTOtP<\/strong> ( Oracle Time-based One-time Password ) is a free tool that adds <strong>2-Factor Authentication<\/strong>\u00a0layer as an extra security when allowing users\u00a0to execute anything inside your\u00a0Oracle Database.<\/p>\n<p>Usage examples of OraTOtP:<\/p>\n<ul>\n<li>Add an extra security layer for your database users, making the user password\u00a0less powerful.<\/li>\n<li>If someone discovers any schema\u00a0password, he will have limited or no access to the\u00a0DB objects.<\/li>\n<li>You want to meet some compliance requirement (e.g.:\u00a0PCI DSS Requirement 8.3)<\/li>\n<\/ul>\n<p>Tested on all Oracle Database versions (SE and EE) from\u00a0<strong>10gR2 until latest 12c.<\/strong><\/p>\n<h1><strong>1. How it Works<\/strong><\/h1>\n<p>After the user connects, his roles will be disabled and the only way to enable them is typing a correct 6-digits token that is\u00a0generated using a\u00a0mobile app. The DBA\u00a0can easily define which roles are required to have <strong>2-Factor Authentication<\/strong>\u00a0before they get\u00a0enabled by someone.<\/p>\n<p>OraTOtP tool is intended to be very easy to setup and use, not requiring any\u00a0major skills for anyone\u00a0to enable it.<\/p>\n<p>You should not enable 2-Factor Authentication for roles used by logins\u00a0with unattended access (application, batch jobs, etc) unless there is some application interface to\u00a0type the token.\u00a0It is also <strong>not<\/strong> recommended to enable it on default roles (DBA, RESOURCE, etc.) as it may impact internal Oracle processes, the most appropriate is that clone these roles with another name and enable this\u00a0protection.<\/p>\n<h1><strong>2. Features<\/strong><\/h1>\n<ul>\n<li>If you\u00a0always\u00a0connect from the same application and machine, you can ask the tool to trust\u00a0it\u00a0for 7 days. So you\u00a0won&#8217;t need to type the token again if \u00a0you\u00a0connect on the database from the exactly same place.<\/li>\n<li>User can reconfigure\u00a0the 2-Factor if changing phone or app.<\/li>\n<li>Protection against tokens brute-force attacks.<\/li>\n<li>The\u00a0token seed is stored encrypted inside the database. User can provide a password for the encryption seed to make it irreversible by anyone (not even me).<\/li>\n<\/ul>\n<h1><strong>3. Instructions<\/strong><\/h1>\n<p>1- Download an Authenticator app for your mobile. I recommend &#8220;<strong>Google Authenticator<\/strong>&#8220;, as it is free, simple and stable:<\/p>\n<ul>\n<li><strong>Android<\/strong>:\u00a0https:\/\/play.google.com\/store\/apps\/details?id=com.google.android.apps.authenticator2<\/li>\n<li><strong>iOS<\/strong>:\u00a0https:\/\/itunes.apple.com\/br\/app\/google-authenticator\/id388497605<\/li>\n<li><strong>Windows Phone<\/strong>:\u00a0https:\/\/www.microsoft.com\/en-us\/store\/p\/authenticator\/9wzdncrfj3rj<\/li>\n<\/ul>\n<p style=\"padding-left: 30px;\">There are also tons of other\u00a0Third-Party apps that are based on the same TOTP algorithm.<\/p>\n<p>2- Install OraTOtP tool in your database (check &#8220;<strong>Installation<\/strong>&#8221; section for more details).<\/p>\n<p>3- CREATE\u00a0or ALTER\u00a0any existing ROLE to be only enabled after 2-Step Authentication is completed (check &#8220;<strong>Usage Example<\/strong>&#8221; section for other examples).<\/p>\n<p><strong><span style=\"color: #800000;\">P.S.: Ensure your system clock is synchronized with UTC and in the correct timezone.<\/span><\/strong><\/p>\n<h1><strong>4. Created Objects<\/strong><\/h1>\n<p>The OraTOtP tool will create 1 new schema (which name you can define during installation) to hold all the packages and tables that will have the\u00a0Time-based One-time Password configuration. This user will be locked and expired and is not intended to be used by anyone.<\/p>\n<p>It consists on:<\/p>\n<ul>\n<li>1 New Schema with:\n<ul>\n<li>3 Packages and their Bodys<\/li>\n<li>1 Procedure<\/li>\n<li>1 Trigger<\/li>\n<li>3 Tables and their Constraints and Indexes<\/li>\n<\/ul>\n<\/li>\n<li>2 Public Synonyms (to avoid schema\u00a0name\u00a0typing)<\/li>\n<li>1 Context (to control 2-Factor authentication)<\/li>\n<\/ul>\n<p>If you have <strong>Enterprise Edition DB<\/strong>, it will also create 1 function and 4 VPD policies to protect the schema\u00a0tables.<\/p>\n<p>If you have <strong>Database Vault Option<\/strong>, it will also create a realm to protect all the schema objects.<\/p>\n<h3><span style=\"text-decoration: underline;\">There are only 3 objects that need to be known:<\/span><\/h3>\n<p>&nbsp;<\/p>\n<ol>\n<li>Package <strong>TWOFACTOR<\/strong> (used to do all tasks related with the 2-Factor. Granted to PUBLIC).<\/li>\n<li>Package <strong>TWOFACTOR_ADMIN<\/strong> (used to do all tasks admin tasks related\u00a0with the 2-Factor. Must be granted to DBAs only).<\/li>\n<li>Procedure <strong>ENABLE_ROLE<\/strong> (used to enable any 2-Factor protected role. Granted to PUBLIC).<\/li>\n<\/ol>\n<p>Those 3 objects are more detailed on &#8220;<strong>Documentation<\/strong>&#8221; section.<\/p>\n<h1><strong>5. Installation<\/strong><\/h1>\n<p>Download ZIP file (check &#8220;<strong>Download<\/strong>&#8221; section for more information) and extract all the files.<\/p>\n<p>Open <strong>SQL*Plus<\/strong> and run INSTALL.sql.<\/p>\n<h4><strong>Example 1:<\/strong><\/h4>\n<ul>\n<li>Install for a local DB.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">[oracle@mydbserver ~]$ sqlplus \/nolog\r\n\r\nSQL*Plus: Release 12.1.0.2.0 Production on Tue Oct 18 13:54:08 2016\r\n\r\nCopyright (c) 1982, 2014, Oracle.  All rights reserved.\r\n\r\nSQL&gt; @INSTALL\r\nSchema Name for 2-Factor [TOTP]: TOTP\r\nString to connect as SYS [\/ as sysdba]: \/ as sysdba\r\nConnected.\r\nDB Vault Users script skipped - Database Vault not enabled.\r\nConnected.\r\nUser created.\r\nConnected.\r\nUser privs granted.\r\nConnected.\r\nObjects created.\r\nPolicies created.\r\nConnected.\r\nDB Vault Realms script skipped - Database Vault not enabled.\r\n=&gt; SCRIPT EXECUTED SUCCESSFULLY! &lt;=<\/pre>\n<h4><strong>Example 2:<\/strong><\/h4>\n<ul>\n<li>Install for a remote database using TNS Names.<\/li>\n<li>Here the DB Vault is enabled on the Database. In that case the script requests extra information.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">[oracle@mydbserver ~]$ sqlplus \/nolog\r\n\r\nSQL*Plus: Release 12.1.0.2.0 Production on Tue Oct 18 11:20:13 2016\r\n\r\nCopyright (c) 1982, 2014, Oracle.  All rights reserved.\r\n\r\nSQL&gt; @INSTALL\r\nSchema Name for 2-Factor [TOTP]:\r\nString to connect as SYS [\/ as sysdba]: sys\/Oracle.123@orcl as sysdba\r\nConnected.\r\nOracle Database Vault Detected.\r\nString to connect as DV Acct Mgr [\/ as sysdba]: dvacctmgr\/Oracle.123@orcl\r\nString to connect as DV Owner [\/ as sysdba]: dvowner\/Oracle.123@orcl\r\nString to connect as DBA [\/ as sysdba]: system\/Oracle.123@orcl\r\nConnected.\r\nUser created.\r\nConnected.\r\nUser privs granted.\r\nConnected.\r\nObjects created.\r\nPolicies created.\r\nConnected.\r\nRealm created.\r\n=&gt; SCRIPT EXECUTED SUCCESSFULLY! &lt;=<\/pre>\n<h4><strong>Example 3:<\/strong><\/h4>\n<ul>\n<li>Install for a remote DB using EZ Connect.<\/li>\n<li>Setting the Schema Name as GAUTH instead of the default TOTP.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">[oracle@mydbserver ~]$ sqlplus \/nolog\r\n\r\nSQL*Plus: Release 12.1.0.2.0 Production on Tue Oct 18 11:20:13 2016\r\n\r\nCopyright (c) 1982, 2014, Oracle.  All rights reserved.\r\n\r\nSQL&gt; @INSTALL\r\nSchema Name for 2-Factor [TOTP]: GAUTH\r\nString to connect as SYS [\/ as sysdba]: sys\/Oracle.123@10.1.1.5\/orcl as sysdba\r\nConnected.\r\nDB Vault Users script skipped - Database Vault not enabled.\r\nConnected.\r\nUser created.\r\nConnected.\r\nUser privs granted.\r\nConnected.\r\nObjects created.\r\nPolicies created.\r\nConnected.\r\nDB Vault Realms script skipped - Database Vault not enabled.\r\n=&gt; SCRIPT EXECUTED SUCCESSFULLY! &lt;=<\/pre>\n<h1><strong>6.\u00a0Documentation<\/strong><\/h1>\n<h4><strong>TWOFACTOR:<\/strong><\/h4>\n<p><strong>This package must be granted to every DB user and is responsible for allowing the user to setup and authenticate for the 2-Fator Auth. Only after that he will be able to ENABLE any role protected with 2-Factor.<\/strong><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>SETUP\u00a0<\/strong>(PPASS IN VARCHAR2 DEFAULT NULL);<\/span><br \/>\nWill setup the current logged in user and generate an URL with a QR Code. This is the first step that must\u00a0be done by anyone. Scan the generated Code with your mobile app. Before running, don&#8217;t forget to enable SERVEROUTPUT.<\/p>\n<p style=\"padding-left: 30px;\">Parameter:<\/p>\n<p style=\"padding-left: 90px;\">PPASS &#8211; Optionally you can add a password to make the\u00a0code seed irreversible by anyone. You can define any password up to 30 characters. It has nothing to do with your user account password, this one is used to encrypt your code generation seed to protect it.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>VALIDATE\u00a0<\/strong>(PCODE IN VARCHAR2, PPASS IN VARCHAR2 DEFAULT NULL);<\/span><br \/>\nAfter the user is SETUP, you must validate it providing a code that is generated by your app. Validation proves that you have setup the mobile app correctly and the code being generated is valid. Only after user is validated that it can authenticate and enable roles that are protected with 2-Factor Authentication.<\/p>\n<p style=\"padding-left: 30px;\">Parameter:<\/p>\n<p style=\"padding-left: 90px;\">PCODE &#8211; Give the code generated by the\u00a0mobile app.<\/p>\n<p style=\"padding-left: 90px;\">PPASS &#8211; If you have done the setup with a password, type it here to decode the seed.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>AUTHENTICATE\u00a0<\/strong>(PCODE IN VARCHAR2, PPASS IN VARCHAR2 DEFAULT NULL);<\/span><br \/>\nNow that user is SETUP and the code generator is VALIDATED, after every new login you need to authenticate it to be able to enable and activate the role having your privileges.<\/p>\n<p style=\"padding-left: 30px;\">Parameter:<\/p>\n<p style=\"padding-left: 90px;\">PCODE &#8211; Give the code generated by the\u00a0mobile app.<\/p>\n<p style=\"padding-left: 90px;\">PPASS &#8211; If you have done the setup with a password, type it here to decode the seed.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>DECONFIG\u00a0<\/strong>(PCODE IN VARCHAR2 DEFAULT NULL, PPASS IN VARCHAR2 DEFAULT NULL);<\/span><br \/>\nWill undo and clean any user configuration. Useful if your changing your mobile app to another phone or you want to rekey your seed. You need to provide a CODE if the user is already validated. If you lost your code generation app and cannot DECONFIG, ask support for the admin can help.<\/p>\n<p style=\"padding-left: 30px;\">Parameter:<\/p>\n<p style=\"padding-left: 90px;\">PCODE &#8211; Give the code generated by the\u00a0mobile app if the\u00a0user is already validated.<\/p>\n<p style=\"padding-left: 90px;\">PPASS &#8211; If you have done the setup with a password, type it here to decode the seed.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>REMEMBER\u00a0<\/strong>(PCODE IN VARCHAR2, PPASS IN VARCHAR2 DEFAULT NULL);<\/span><br \/>\nThis procedure will remember the machine, application and connection credentials your are coming from for 7 days. This location will be configured as trusted. During that time, when you establish a new connection it will be automatically AUTHENTICATE. All you need is to enable the role.<\/p>\n<p style=\"padding-left: 30px;\">Parameter:<\/p>\n<p style=\"padding-left: 90px;\">PCODE &#8211; Give the code generated by the\u00a0mobile app.<\/p>\n<p style=\"padding-left: 90px;\">PPASS &#8211; If you have done the setup with a password, type it here to decode the seed.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>FORGET<\/strong>;<\/span><br \/>\nThis procedure will\u00a0clean all the remembered connections sources linked to your user.<\/p>\n<h4><strong>TWOFACTOR_ADMIN:<\/strong><\/h4>\n<p><strong>This package is very similar to TWOFACTOR package unless that you can also manage other users with it. Thus it must be granted\u00a0only to 2-Factor Admins (or DBA&#8217;s). Basically all the procedures are the same adding a &#8220;PUSER&#8221; parameter.<\/strong><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>SETUP<\/strong> (PUSER IN VARCHAR2, PPASS IN VARCHAR2 DEFAULT NULL, PGAP IN NUMBER DEFAULT NULL);<\/span><br \/>\nSame as\u00a0TWOFACTOR.SETUP, unless that it will setup the user specified by PUSER parameter\u00a0(not the session user).<\/p>\n<p style=\"padding-left: 30px;\">Parameter:<\/p>\n<p style=\"padding-left: 90px;\">PUSER &#8211; Username affected by the procedure.<\/p>\n<p style=\"padding-left: 90px;\">PPASS &#8211; Optionally you can add a password to make your code seed irreversible by any DB admin.<\/p>\n<p style=\"padding-left: 90px;\">PGAP &#8211; Time gap\u00a0in seconds to also accept codes based on time difference errors. One new code is generated every 30 seconds, however, to avoid problems, by default (if null input) we add a gap of\u00a0480 seconds (8 minutes) = 4 minutes up and down. That means that if your mobile clock is at 12h00 and server clock is at 12h04, your generated code will still be accessible. The accepted limit is\u00a01200 seconds (20 minutes) = 10 minutes up and down.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>VALIDATE<\/strong> (PUSER IN VARCHAR2, PCODE IN VARCHAR2, PPASS IN VARCHAR2 DEFAULT NULL);<\/span><br \/>\nSame as\u00a0TWOFACTOR.VALIDATE, unless that it will validate\u00a0the user specified by PUSER parameter\u00a0(not the session user).<\/p>\n<p style=\"padding-left: 30px;\">Parameter:<\/p>\n<p style=\"padding-left: 90px;\">PUSER &#8211; Username affected by the procedure.<\/p>\n<p style=\"padding-left: 90px;\">PCODE &#8211; Give the code generated by user mobile app.<\/p>\n<p style=\"padding-left: 90px;\">PPASS &#8211; If user\u00a0have done the setup with a password, type it here to decode the seed.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>AUTHENTICATE<\/strong> (PCODE IN VARCHAR2, PPASS IN VARCHAR2 DEFAULT NULL);<\/span><br \/>\nSame as\u00a0TWOFACTOR.AUTHENTICATE. You cannot authenticate for another user.<\/p>\n<p style=\"padding-left: 30px;\">Parameter:<\/p>\n<p style=\"padding-left: 90px;\">PCODE &#8211; Give the code generated by user mobile app.<\/p>\n<p style=\"padding-left: 90px;\">PPASS &#8211; If you have done the setup with a password, type it here to decode the seed.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>DECONFIG<\/strong> (PUSER IN VARCHAR2, PCODE IN VARCHAR2 DEFAULT NULL, PPASS IN VARCHAR2 DEFAULT NULL, PISADMIN IN BOOLEAN DEFAULT TRUE);<\/span><br \/>\nSame as\u00a0TWOFACTOR.DECONFIG, unless that it will deconfigure the user specified by PUSER parameter\u00a0(not the session user).<\/p>\n<p style=\"padding-left: 30px;\">Parameter:<\/p>\n<p style=\"padding-left: 90px;\">PUSER &#8211; Username affected by the procedure.<\/p>\n<p style=\"padding-left: 90px;\">PCODE &#8211; Give the code generated by user mobile app.\u00a0Ignored if PISADMIN is true (default behavior).<\/p>\n<p style=\"padding-left: 90px;\">PPASS &#8211; If user\u00a0have done the setup with a password, type it here to decode the seed.<\/p>\n<p style=\"padding-left: 90px;\">PISADMIN &#8211; When this parameter is true\u00a0(default behavior), you don&#8217;t need to give a code to deconfigure already\u00a0validated users.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>REMEMBER<\/strong> (PCODE IN VARCHAR2, PPASS IN VARCHAR2 DEFAULT NULL, PINT IN INTERVAL DAY TO SECOND DEFAULT NULL);<\/span><br \/>\nSame as\u00a0TWOFACTOR.REMEMBER. You cannot remember login specs\u00a0for another user.<\/p>\n<p style=\"padding-left: 30px;\">Parameter:<\/p>\n<p style=\"padding-left: 90px;\">PCODE &#8211; Give the code generated by user\u00a0mobile app.<\/p>\n<p style=\"padding-left: 90px;\">PPASS &#8211; If user\u00a0have done the setup with a password, type it here to decode the seed.<\/p>\n<p style=\"padding-left: 90px;\">PINT &#8211; Interval of days to remember the credentials. If not specified, it defaults to 7 days.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>FORGET<\/strong> (PUSER IN VARCHAR2);<\/span><br \/>\nSame as\u00a0TWOFACTOR.FORGET, unless that it will forget\u00a0the login specs of the user specified by PUSER parameter\u00a0(not the session user).<\/p>\n<p style=\"padding-left: 30px;\">Parameter:<\/p>\n<p style=\"padding-left: 90px;\">PUSER &#8211; Username affected by the procedure.<\/p>\n<h4><strong>ENABLE_ROLE:<\/strong><\/h4>\n<p><strong>This procedure is used to enable a protected role.<\/strong><\/p>\n<p style=\"padding-left: 30px;\"><span style=\"color: #0000ff;\"><strong>ENABLE_ROLE<\/strong> (ROLE_NAME IN VARCHAR2);<br \/>\n<\/span>Will add the protected role named passed as parameter to your list of enabled roles, by running &#8220;SET ROLE&#8221;. You must be authenticated in 2-Factor to be able to execute it.<\/p>\n<p style=\"padding-left: 30px;\">Parameter:<\/p>\n<p style=\"padding-left: 60px;\">ROLE_NAME &#8211; Protected role name that you want to enable in your session.<\/p>\n<h4><strong>TABLES and COLUMNS:<\/strong><\/h4>\n<p>Check tables and columns comments.<\/p>\n<h1><strong>7. Usage Example<\/strong><\/h1>\n<p>First step is to create a ROLE that you want to be protected by 2-Factor authenticaion:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"oracledb\">SQL&gt; CREATE ROLE APPOBJACCESS IDENTIFIED USING TOTP.ENABLE_ROLE;\r\n\r\nRole created.\r\n\r\nSQL&gt;<\/pre>\n<p><em>P.S: You can optionally\u00a0alter\u00a0an existing roles to be only enabled after user is authenticated by 2-Factor.<\/em><\/p>\n<p>Now, let&#8217;s create a new user to show how it works:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"oracledb\">SQL&gt; CREATE USER USER1 IDENTIFIED BY \"User1\";\r\n\r\nUser created.\r\n\r\nSQL&gt; GRANT CREATE SESSION TO USER1;\r\n\r\nGrant succeeded.\r\n\r\nSQL&gt; GRANT APPOBJACCESS TO USER1;\r\n\r\nGrant succeeded.\r\n\r\nSQL&gt;<\/pre>\n<p>Role is created and granted to USER1, let&#8217;s try to connect and enable the role:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"oracledb\">SQL&gt; conn User1\/User1\r\nConnected.\r\nSQL&gt; select * from session_roles;\r\n\r\nno rows selected\r\n\r\nSQL&gt; set role APPOBJACCESS;\r\nset role APPOBJACCESS\r\n*\r\nERROR at line 1:\r\nORA-01924: role 'APPOBJACCESS' not granted or does not exist\r\n\r\nSQL&gt; exec enable_role('APPOBJACCESS');\r\nBEGIN enable_role('APPOBJACCESS'); END;\r\n*\r\nERROR at line 1:\r\nORA-20000: User not authenticated in 2Factor.\r\nORA-06512: at \"TOTP.ENABLE_ROLE\", line 14\r\nORA-06512: at line 1\r\n\r\nSQL&gt;<\/pre>\n<p>As you can see,\u00a0role cannot be enabled via set command. The right way is to use the <strong>enable_role<\/strong> procedure, however, the user must authenticate first. As this user is not even yet configured, let&#8217;s set it up:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"oracledb\">SQL&gt; set serveroutput on\r\nSQL&gt; set lines 1000\r\nSQL&gt; exec twofactor.setup;\r\nhttps:\/\/www.google.com\/chart?chs=200x200&chld=M|0&cht=qr&chl=%6F%74%70%61%75%74%68%3A%2F%2F%74%6F%74%70%2F%55%53%45%52%31%40%4F%52%43%4C%3F%73%65%63%72%65%74%3D%56%53%4D%34%50%52%35%41%4B%56%44%52%47%59%55%35%26%69%73%73%75%65%72%3D%44%42%20%53%65%72%76%65%72%20%2D%20%6F%72%63%6C%2E%75%73%2E%6F%72%61%63%6C%65%2E%63%6F%6D\r\n\r\nPL\/SQL procedure successfully completed.\r\n\r\nSQL&gt;<\/pre>\n<p><em>P.S: If you forget to enable serveroutput before running the SETUP\u00a0procedure, just run the DECONFIG, enable it and then rerun setup.<\/em><\/p>\n<p>Open the returned link address in a browser and scan the QR Code\u00a0using &#8220;Google Authenticator&#8221; (or any other TOTP app that you prefer):<\/p>\n<p id=\"WTcrSot\"><img loading=\"lazy\" decoding=\"async\" width=\"641\" height=\"299\" class=\"size-full wp-image-2291 aligncenter\" src=\"http:\/\/dev.dbarj.com.br\/wp-content\/uploads\/2016\/10\/img_57fecd47862d5.png\" alt=\"\" srcset=\"https:\/\/dev.dbarj.com.br\/wp-content\/uploads\/2016\/10\/img_57fecd47862d5.png 641w, https:\/\/dev.dbarj.com.br\/wp-content\/uploads\/2016\/10\/img_57fecd47862d5-300x140.png 300w\" sizes=\"auto, (max-width: 641px) 100vw, 641px\" \/><\/p>\n<p>After your app is configured, it will start generating the codes as below:<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"wp-image-2292 size-medium aligncenter\" src=\"http:\/\/dev.dbarj.com.br\/wp-content\/uploads\/2016\/10\/WhatsApp-Image-2016-10-12-at-20.47.41-169x300.jpeg\" width=\"169\" height=\"300\" srcset=\"https:\/\/dev.dbarj.com.br\/wp-content\/uploads\/2016\/10\/WhatsApp-Image-2016-10-12-at-20.47.41-169x300.jpeg 169w, https:\/\/dev.dbarj.com.br\/wp-content\/uploads\/2016\/10\/WhatsApp-Image-2016-10-12-at-20.47.41-576x1024.jpeg 576w, https:\/\/dev.dbarj.com.br\/wp-content\/uploads\/2016\/10\/WhatsApp-Image-2016-10-12-at-20.47.41.jpeg 720w\" sizes=\"auto, (max-width: 169px) 100vw, 169px\" \/>You\u00a0can now validate:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"oracledb\">SQL&gt; exec twofactor.validate(682286);\r\n\r\nPL\/SQL procedure successfully completed.\r\n\r\nSQL&gt;<\/pre>\n<p>With 2-Factor\u00a0validated, from now on all you\u00a0need to do after a creating a new connection is authenticate and enable the role:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"oracledb\">SQL&gt; select * from session_roles;\r\n\r\nno rows selected\r\n\r\nSQL&gt; exec twofactor.authenticate(390564);\r\n\r\nPL\/SQL procedure successfully completed.\r\n\r\nSQL&gt; exec enable_role('APPOBJACCESS');\r\n\r\nPL\/SQL procedure successfully completed.\r\n\r\nSQL&gt; select * from session_roles;\r\n\r\nROLE\r\n------------------------------\r\nAPPOBJACCESS\r\n\r\nSQL&gt;<\/pre>\n<p>Optionally, you can ask the 2-Factor authentication system to trust in your location\u00a0for the next 7 days, so you won&#8217;t need to re-authenticate after every new login coming from the same machine, terminal, IP, program and OS user:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"oracledb\">SQL&gt; conn User1\/User1\r\nConnected.\r\nSQL&gt; exec enable_role('APPOBJACCESS');\r\nBEGIN enable_role('APPOBJACCESS'); END;\r\n*\r\nERROR at line 1:\r\nORA-20000: User not authenticated in 2Factor.\r\nORA-06512: at \"TOTP.ENABLE_ROLE\", line 14\r\nORA-06512: at line 1\r\n\r\nSQL&gt; exec twofactor.authenticate(388648);\r\n\r\nPL\/SQL procedure successfully completed.\r\n\r\nSQL&gt; exec enable_role('APPOBJACCESS');\r\n\r\nPL\/SQL procedure successfully completed.\r\n\r\nSQL&gt; exec twofactor.remember(471508);\r\n\r\nPL\/SQL procedure successfully completed.\r\n\r\nSQL&gt; conn User1\/User1\r\nConnected.\r\nSQL&gt; exec enable_role('APPOBJACCESS');\r\n\r\nPL\/SQL procedure successfully completed.\r\n\r\nSQL&gt;\r\n<\/pre>\n<h1><strong>8. Download<\/strong><\/h1>\n<p><a href=\"https:\/\/github.com\/dbarj\/OraTOtP\/archive\/master.zip\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/dbarj\/OraTOtP\/archive\/master.zip<\/a><\/p>\n<blockquote>\n<p style=\"padding-left: 30px;\">&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>\nChecksum information<br \/>\n&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>\nName: OraTOtP-1.00.zip<br \/>\nSize: 30248 bytes (0 MB)<br \/>\nCRC32: 9532060D<br \/>\nCRC64: F95F37109D5196B1<br \/>\nSHA256: 2339020753EE758969E2E500D5A4A29DD3D1FDFD9B14844EFD272567D4F54A4F<br \/>\nSHA1: C458801D32AC2B192ABD7AF2FC74099B08E5C269<br \/>\nBLAKE2sp: DF7E1399F2912244A02DEC6EFECEC617277321E0FD35AAB66AD7625F8DB3EA7F<\/p>\n<\/blockquote>\n<b>Have you enjoyed? Please leave a comment or give a ?!<\/b>\n<div class='watch-action'><div class='watch-position align-left'><div class='action-like'><a class='lbg-style2 like-2266 jlk' href='javascript:void(0)' data-task='like' data-post_id='2266' data-nonce='b7aaf4ff99' rel='nofollow'><img class='wti-pixel' src='https:\/\/dev.dbarj.com.br\/wp-content\/plugins\/wti-like-post\/images\/pixel.gif' title='Like' \/><span class='lc-2266 lc'>0<\/span><\/a><\/div><\/div> <div class='status-2266 status align-left'><\/div><\/div><div class='wti-clear'><\/div>","protected":false},"excerpt":{"rendered":"<p>OraTOtP OraTOtP ( Oracle Time-based One-time Password ) is a free tool that adds 2-Factor Authentication\u00a0layer as an extra security when allowing users\u00a0to execute anything inside your\u00a0Oracle Database. Usage examples of OraTOtP: Add an extra security layer for your database users, making the user password\u00a0less powerful. If someone discovers any schema\u00a0password, he will have limited &hellip; <\/p>\n<p><a class=\"more-link btn\" href=\"https:\/\/dev.dbarj.com.br\/en\/oratotp-oracle-time-based-one-time-password\/\">Continue reading<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2266","page","type-page","status-publish","hentry","nodate","item-wrap"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>OraTOtP ( Oracle Time-based One-time Password ) - DBA - Rodrigo Jorge - Oracle Tips and Guides<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/dev.dbarj.com.br\/en\/oratotp-oracle-time-based-one-time-password\/\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/oratotp-oracle-time-based-one-time-password\\\/\",\"url\":\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/oratotp-oracle-time-based-one-time-password\\\/\",\"name\":\"OraTOtP ( Oracle Time-based One-time Password ) - DBA - Rodrigo Jorge - Oracle Tips and Guides\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/oratotp-oracle-time-based-one-time-password\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/oratotp-oracle-time-based-one-time-password\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/dev.dbarj.com.br\\\/wp-content\\\/uploads\\\/2016\\\/10\\\/img_57fecd47862d5.png\",\"datePublished\":\"2016-11-04T02:21:38+00:00\",\"dateModified\":\"2020-01-17T10:02:53+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/oratotp-oracle-time-based-one-time-password\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/oratotp-oracle-time-based-one-time-password\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/oratotp-oracle-time-based-one-time-password\\\/#primaryimage\",\"url\":\"http:\\\/\\\/dev.dbarj.com.br\\\/wp-content\\\/uploads\\\/2016\\\/10\\\/img_57fecd47862d5.png\",\"contentUrl\":\"http:\\\/\\\/dev.dbarj.com.br\\\/wp-content\\\/uploads\\\/2016\\\/10\\\/img_57fecd47862d5.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/oratotp-oracle-time-based-one-time-password\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"OraTOtP ( Oracle Time-based One-time Password )\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/#website\",\"url\":\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/\",\"name\":\"DBA - Rodrigo Jorge - Oracle Tips and Guides\",\"description\":\"Blog about Databases, Security and High Availability\",\"publisher\":{\"@id\":\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/#\\\/schema\\\/person\\\/28a44ca3a6633fe4156ad1ea209d40a9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/dev.dbarj.com.br\\\/en\\\/#\\\/schema\\\/person\\\/28a44ca3a6633fe4156ad1ea209d40a9\",\"name\":\"DBA RJ\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/dev.dbarj.com.br\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/RodrigoJorgePOUG19.png\",\"url\":\"https:\\\/\\\/dev.dbarj.com.br\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/RodrigoJorgePOUG19.png\",\"contentUrl\":\"https:\\\/\\\/dev.dbarj.com.br\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/RodrigoJorgePOUG19.png\",\"width\":712,\"height\":712,\"caption\":\"DBA RJ\"},\"logo\":{\"@id\":\"https:\\\/\\\/dev.dbarj.com.br\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/RodrigoJorgePOUG19.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"OraTOtP ( Oracle Time-based One-time Password ) - DBA - Rodrigo Jorge - Oracle Tips and Guides","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/dev.dbarj.com.br\/en\/oratotp-oracle-time-based-one-time-password\/","twitter_misc":{"Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/dev.dbarj.com.br\/en\/oratotp-oracle-time-based-one-time-password\/","url":"https:\/\/dev.dbarj.com.br\/en\/oratotp-oracle-time-based-one-time-password\/","name":"OraTOtP ( Oracle Time-based One-time Password ) - DBA - Rodrigo Jorge - Oracle Tips and Guides","isPartOf":{"@id":"https:\/\/dev.dbarj.com.br\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/dev.dbarj.com.br\/en\/oratotp-oracle-time-based-one-time-password\/#primaryimage"},"image":{"@id":"https:\/\/dev.dbarj.com.br\/en\/oratotp-oracle-time-based-one-time-password\/#primaryimage"},"thumbnailUrl":"http:\/\/dev.dbarj.com.br\/wp-content\/uploads\/2016\/10\/img_57fecd47862d5.png","datePublished":"2016-11-04T02:21:38+00:00","dateModified":"2020-01-17T10:02:53+00:00","breadcrumb":{"@id":"https:\/\/dev.dbarj.com.br\/en\/oratotp-oracle-time-based-one-time-password\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/dev.dbarj.com.br\/en\/oratotp-oracle-time-based-one-time-password\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/dev.dbarj.com.br\/en\/oratotp-oracle-time-based-one-time-password\/#primaryimage","url":"http:\/\/dev.dbarj.com.br\/wp-content\/uploads\/2016\/10\/img_57fecd47862d5.png","contentUrl":"http:\/\/dev.dbarj.com.br\/wp-content\/uploads\/2016\/10\/img_57fecd47862d5.png"},{"@type":"BreadcrumbList","@id":"https:\/\/dev.dbarj.com.br\/en\/oratotp-oracle-time-based-one-time-password\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/dev.dbarj.com.br\/en\/"},{"@type":"ListItem","position":2,"name":"OraTOtP ( Oracle Time-based One-time Password )"}]},{"@type":"WebSite","@id":"https:\/\/dev.dbarj.com.br\/en\/#website","url":"https:\/\/dev.dbarj.com.br\/en\/","name":"DBA - Rodrigo Jorge - Oracle Tips and Guides","description":"Blog about Databases, Security and High Availability","publisher":{"@id":"https:\/\/dev.dbarj.com.br\/en\/#\/schema\/person\/28a44ca3a6633fe4156ad1ea209d40a9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/dev.dbarj.com.br\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/dev.dbarj.com.br\/en\/#\/schema\/person\/28a44ca3a6633fe4156ad1ea209d40a9","name":"DBA RJ","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/dev.dbarj.com.br\/wp-content\/uploads\/2019\/09\/RodrigoJorgePOUG19.png","url":"https:\/\/dev.dbarj.com.br\/wp-content\/uploads\/2019\/09\/RodrigoJorgePOUG19.png","contentUrl":"https:\/\/dev.dbarj.com.br\/wp-content\/uploads\/2019\/09\/RodrigoJorgePOUG19.png","width":712,"height":712,"caption":"DBA RJ"},"logo":{"@id":"https:\/\/dev.dbarj.com.br\/wp-content\/uploads\/2019\/09\/RodrigoJorgePOUG19.png"}}]}},"_links":{"self":[{"href":"https:\/\/dev.dbarj.com.br\/en\/wp-json\/wp\/v2\/pages\/2266","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dev.dbarj.com.br\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/dev.dbarj.com.br\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/dev.dbarj.com.br\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.dbarj.com.br\/en\/wp-json\/wp\/v2\/comments?post=2266"}],"version-history":[{"count":2,"href":"https:\/\/dev.dbarj.com.br\/en\/wp-json\/wp\/v2\/pages\/2266\/revisions"}],"predecessor-version":[{"id":4379,"href":"https:\/\/dev.dbarj.com.br\/en\/wp-json\/wp\/v2\/pages\/2266\/revisions\/4379"}],"wp:attachment":[{"href":"https:\/\/dev.dbarj.com.br\/en\/wp-json\/wp\/v2\/media?parent=2266"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}