oracle stored procedures encryption key - oracle

How to update stored procedures encryption key in oracle 11g.
(val IN varchar) RETURN varchar AS
outstr varchar(10);
descr varchar(255);
BEGIN
-- Encryption Key For Encryption
secret_code := '123456788765432112345678';
--create instance of OLE object on an instance of SQL Server;
success = 0
EXEC rc = sp_OACreate 'CAPICOM.EncryptedData', object OUT
if rc <> 0
begin
exec sp_oageterrorinfo object, src out, descr out end
method_call := 'SetSecret("' + Secret_code + '")'
RETURN (outstr);
END;

I am not sure what are you looking for.
Check this
and also you may review this too

Stored procedures can be WRAPPED which is a form of encryption. But you can't update the key as it is hard-coded into the wrapping algorithm.
This might make you think they are susceptible to be cracked. They are and unwrappers are available.

Related

Oracle Context equivalent for DB2

I am currently migrating from oracle to DB2. I have actively used sys_context in most of the applications to get the userID of logged in user through sessions(IIS and .net framework).
I am looking to convert the following set of scripts from oracle to DB2. So far not able to find any equivalent for oracle context in DB2.
SQL> create context my_ctx
2 using pkg_ctx;
Context created.
SQL> create package pkg_ctx
2 as
3 procedure set_context;
4 end;
5 /
Package created.
SQL> create or replace package body pkg_ctx
2 as
3 procedure set_context
4 as
5 begin
6 dbms_session.set_context( 'MY_CTX', 'USERNAME', 'test' );
7 end;
8 end;
9 /
Package body created.
SQL> exec pkg_ctx.set_context;
PL/SQL procedure successfully completed.
SQL> select sys_context( 'MY_CTX', 'USERNAME' )
2 from dual;
SYS_CONTEXT('MY_CTX','USERNAME')
-------------------------------------------------------------------------------
test
Assuming you work with Db2 for LUW, you can use one of the CURRENT CLIENT_* registry variables to pass session context information from the client application to the server. For example, during the session initialization on the client side you would issue SET CURRENT CLIENT_USERID='stacky', then on the server that variable can be read by a routine or a trigger.
It worked like this, haven't tried it at application level. But from the database tried to register 2 users from 2 different instances of the same database on DB2.
call sysproc.wlm_set_client_info('stacky',null,null,null,null);
select wlm_set_client_info from sysibm.sysdummy1;
returns stacky
from another instance of the same database
call sysproc.wlm_set_client_info('test',null,null,null,null);
select wlm_set_client_info from sysibm.sysdummy1;
returns test.
Will try this from the application level through creating sessions of the users, will monitor how exactly this works with the special registers.
Not sure if this is the exact way to do this, will explore more and keep updated.
For replicating a similar situation in our environment, while doing the migration from oracle to DB2 LUW.
The below procedure sets up the all the context values in user_id (limited to varchar 255) field which we need as as 'key1:value1|key2:value2|'
Procedure to setup the context values
CREATE OR REPLACE PROCEDURE setup_context(pValues IN VARCHAR)
IS
lValues VARCHAR2(255) := pValues;
BEGIN
--save the as is
wlm_set_client_info(lValues, NULL, NULL, NULL, NULL);
END;
Procedure to set the value of the desired key
CREATE OR REPLACE FUNCTION sys_context(prefix IN VARCHAR) RETURN VARCHAR IS
lValues VARCHAR2(255);
lParam VARCHAR2(255);
lKey VARCHAR2(255);
lValue VARCHAR2(255);
lIndex PLS_INTEGER;
BEGIN
--get the data from the current session
SELECT CURRENT CLIENT_USERID INTO lValues FROM dual;
LOOP
EXIT WHEN lValues IS NULL OR LENGTH(lValues) = 0;
lIndex := instr(lValues, '|');
IF lIndex > 0 THEN
lParam := substr(lValues, 1, lIndex-1);
lValues := substr(lValues, lIndex+1);
ELSE
lParam := lValues;
lValues := NULL;
END IF;
lIndex := instr(lParam, ':');
lKey := substr(lParam, 1, lIndex-1);
lValue := substr(lParam, lIndex+1);
--get the matching value
IF(lKey = prefix ) Then
RETURN lValue;
END IF;
END LOOP;
RETURN '';
END;
reference : https://www.ibm.com/support/knowledgecenter/en/SSEPEK_11.0.0/sqlref/src/tpc/db2z_sp_wlmsetclientinfo.html

How to encrypt nvarchar column in oracle?

I have a table containing nvarchar datatype columns (contains text in different languages). I want to encrypt data before inserting into table and decrypt the same while fetching records.
Please suggest how i can achieve this.
Encryption and decryption should be done through a private key.
Hoping, my question is clear. Please confirm if i need to provide more information.
Note that it is probably wiser to crypt and decrypt your data directly in your application rather than in the database.
You can use Oracle's DBMS_CRYPTO package. There is an example in the middle of the documentation page.
First you need to make a package to access the cipher type from SQL expression. Let's say you want AES256 in CBC mode with padding:
CREATE PACKAGE pkg_so_42979606
AS
FUNCTION cipher_type RETURN PLS_INTEGER;
END pkg_so_42979606;
/
CREATE PACKAGE BODY pkg_so_42979606
AS
ctype CONSTANT PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_AES256
+ DBMS_CRYPTO.CHAIN_CBC
+ DBMS_CRYPTO.PAD_PKCS5;
FUNCTION cipher_type RETURN PLS_INTEGER
IS
BEGIN
RETURN ctype;
END;
END pkg_so_42979606;
/
Then you will need a key. You can ask Oracle to generate one. To easily handle it I'll move it in Base64. Let's draw one:
DECLARE
key_bytes_raw RAW(32);
key_char NVARCHAR2(64);
BEGIN
key_bytes_raw := DBMS_CRYPTO.RANDOMBYTES(32);
key_char := UTL_I18N.RAW_TO_CHAR(UTL_ENCODE.BASE64_ENCODE(key_bytes_raw), 'AL32UTF8');
DBMS_OUTPUT.PUT_LINE('Key: ' || key_char);
END;
/
Key: pMV3D4xhyfNxp3YyfLWzAErGcKkIjK3X6uc/WIeVTls=
Thus the cipher key I'll use is pMV3D4xhyfNxp3YyfLWzAErGcKkIjK3X6uc/WIeVTls=.
Now I'll use a test table
CREATE TABLE so_42979606 (
id NUMBER PRIMARY KEY,
data NVARCHAR2(2000));
You can insert encrypted data:
INSERT INTO so_42979606
VALUES (1,
DBMS_CRYPTO.ENCRYPT(UTL_I18N.STRING_TO_RAW('My clear data', 'AL32UTF8'),
pkg_so_42979606.cipher_type(),
UTL_ENCODE.BASE64_DECODE(UTL_I18N.STRING_TO_RAW('pMV3D4xhyfNxp3YyfLWzAErGcKkIjK3X6uc/WIeVTls=', 'AL32UTF8'))));
And retrieve the encrypted data in clear.
SELECT id, UTL_I18N.RAW_TO_NCHAR(DBMS_CRYPTO.DECRYPT(data,
pkg_so_42979606.cipher_type(),
UTL_ENCODE.BASE64_DECODE(UTL_I18N.STRING_TO_RAW('pMV3D4xhyfNxp3YyfLWzAErGcKkIjK3X6uc/WIeVTls=', 'AL32UTF8'))),
'AL32UTF8') data
FROM so_42979606;
ID DATA
-- ----------------------
1 My clear data

how can I encode string in HMAC-SHA256 using pl/sql?

I'm working on REST API authorization in PL/SQL using Oracle database 11g Express Edition. I have api_key, nonce and signature as IN variables for every procedure.
Signature is a HMAC-SHA256 encoded string containing api_secret stored in my database. I want check if signature matching my api_secret in database.
My question is how can I encode string in HMAC-SHA256 using pl/sql?
There is SHA256 PL/SQL Implementation for Oracle 10g,11g by CruiserX.
Download the package from here.
Compile the package and package body in sqlplus.
Call the functions like this:
SQL> select sha256.encrypt('test message') from dual;
-- output: 3f0a377ba0a4a460ecb616f6507ce0d8cfa3e704025d4fda3ed0c5ca05468728
SQL> select sha256.encrypt_raw('74657374206D657373616765') from dual;
-- output: 3f0a377ba0a4a460ecb616f6507ce0d8cfa3e704025d4fda3ed0c5ca05468728
sha256.encrypt for Oracle 10g,11g by CruiserX was huge help for my HMAC-SHA256 API authorization in oracle XE.
Complete source code for my version with hmac-sha256 API authorization in oracle 11g XE you can find in my plsql_hmac-sha256 git project. But to perform HMAC keying we basically need store some basic information like nonce of last user request. And of course some function for hashing in my case (oracle 11gXE) sha256.encrypt . but in newer version oracle did provide better buil-in options for that like dbms_crypto.hash function.
PROCEDURE HMAC_AUTHORIZATION (i_api_key IN VARCHAR2, i_api_nonce IN NUMBER, i_api_sign IN VARCHAR, R OUT NUMBER)
IS
p_auth_id NUMBER(10);
p_api_sign_msg VARCHAR2(500);
p_api_nonce NUMBER(35);
p_api_sign VARCHAR2(500);
system_sign VARCHAR2(500);
BEGIN
SELECT AUTH_ID, API_NONCE INTO p_auth_id, p_api_nonce FROM USER_AUTH WHERE API_KEY = i_api_key AND AUTH_STATUS = 1 AND API_NONCE < i_api_nonce;
/* User signature */
p_api_sign_msg := p_auth_id || i_api_key || i_api_nonce;
p_api_sign := sha256.encrypt(p_api_sign_msg);
/* system signature */
system_sign := sha256.encrypt(p_auth_id || i_api_key || i_api_nonce);
IF p_api_sign = system_sign THEN
UPDATE USER_AUTH SET REQUESTS_COUNT = REQUESTS_COUNT+1, API_NONCE = i_api_nonce, LAST_REQUEST = SYSDATE WHERE API_KEY = i_api_key AND AUTH_STATUS = 1 AND AUTH_ID = p_auth_id;
commit;
R := 1;
ELSE
R := 0;
END IF;
EXCEPTION WHEN NO_DATA_FOUND THEN
R := 0;
WHEN OTHERS THEN
R := 0;
END HMAC_AUTHORIZATION;
Thanks for help. Maybe someone will find this useful :)

Oracle equivalent of stored procedure that returns an inline table?

Example in T-SQL (SQL Server - taken from here):
CREATE PROC proc_authors
#au_lname VARCHAR(40)
AS
SELECT
au_id, au_fname, au_lname, city, state
FROM authors
WHERE au_lname = #au_lname
go
Is it possible in Oracle to create a stored procedure that returns an inline table (without declaring a type - like the above)? If not, what would be the closest alternative? i.e. declare inline type, then use it. The idea is to minimize number of DB permissions that are granted.
Please include sample code as part of your answer.
Reasoning behind using stored procedure vs function - we have legacy software that can only execute stored procedures, or raw queries. It appears that only stored procedures in there have support for parameterized execution, which is what we are after.
try this with ref cursor
PROCEDURE proc_get_tada(ip_user IN VARCHAR2,
op_error_code OUT NUMBER,
op_cursor OUT SYS_REFCURSOR,) AS
BEGIN
OPEN op_cursor FOR
SELECT * FROM your_table yt where yt.user = ip_user;
EXCEPTION
WHEN OTHERS THEN
op_error_code := -1;
END proc_get_tada;
you will get collection of all data from you table you can iterate in java or calling program.
Maybe you are searching for something like this:
create table author
(
au_id number,
au_name varchar2(100)
);
insert into author (au_id, au_name) values(1, 'ME');
create or replace function getAuthor(auName varchar2)
return author%rowtype
is
retval author%rowtype;
begin
select * into retval from author where au_name=auName;
return retval;
end;
declare
auth author%rowtype;
begin
auth := getAuthor('ME');
dbms_output.put_line(auth.au_id);
end;

one way encryption oracle

is there a way to do one way encryption for password in oracle? i'm passing in password from a textfield and would like to call a stored procedure in oralce and inside that stored procedure, it would encrypt the password. Thank you
Encryption is, by definition, two-way. You would never encrypt a password. I expect that you really want to hash the password. And you wouldn't want to just hash the password, you'd really want to combine the password with some sort of random salt and hash that.
You'd use the dbms_crypto.hash function to compute the hash and the dbms_random.string function to generate the salt. Something like
DECLARE
l_salt varchar2(50);
l_user varchar2(50);
l_pwd varchar2(50);
l_string_to_hash varchar2(150);
l_hash raw(150);
BEGIN
l_salt := dbms_random.string( 'P', 50 );
l_string_to_hash := l_user || l_pwd || l_salt;
l_hash := dbms_crypto.hash( utl_i18n.string_to_raw( l_string_to_hash, 'AL32UTF8' ),
dbms_crypto.hash_sh1 );
END;
See also this askTom discussion (which starts off using the older dbms_obfuscation_toolkit package rather than the dbms_crypto package) for more background on why you'd use a hash, the benefits of salting the password, etc.

Resources