Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 6249
  • Last Modified:

Need to encrypt password

Hello Experts,
I have a user table that has user name and password columns.  I would like to encrypt the password column.  I also have a java application that retrieves user name and password. It then does a plain string compare between password that was typed in and the one that is in the database.  If they match, the user is logged in.  

I would like to encrypt the password on the database side and then somehow be able to compare the password that was typed in by the user and the encrypted password in the database.  I would appreciate your help in getting this to work.

I am using JDK 1.4 and in conjunction with Oracle 8.1.7 db.
0
Dmitriy
Asked:
Dmitriy
1 Solution
 
androknegoCommented:
Hi

For our DB we use the MD5, which is a pretty strong one-way encryption algorithm. In other words, you calculate MD5 (username || password) and store it and then each time a user logs in you calculate MD5 (provided_username || provided_pass) and compare it to the stored value. A thing to remember is that if you forget the password you can't guess the old way, you can just reset it to a new value.

In Oracle you can use  dbms_obfuscation_toolkit.md5 or you can do it in Java too (1.4 has got it somewhere, forgot where exactly). Mind that this function may take a couple of tenths of a second to run (depends on the CPU) as it uses extensive calculations. It's pretty secure though.

HTH

Andrew
0
 
ora_user2003Commented:
hI DMITRIY,


TRY THE FOLLOWING


declare
input_string varchar2(20):='DMITRIY1';
key_string varchar2(20):='CODEWORD';
encrypted_string varchar2(200);
begin
dbms_obfuscation_toolkit.DESEncrypt(
input_string => input_string,
key_string => key_string,
encrypted_string => encrypted_string );
      dbms_output.put_line('> Encrypted string             : ' ||
                   encrypted_string);
end ;

AND BUILD YOUR LOGIC ACCORDINGLY ON THE SAME

 FOR ENCRYPTING ...




0
Veeam Disaster Recovery in Microsoft Azure

Veeam PN for Microsoft Azure is a FREE solution designed to simplify and automate the setup of a DR site in Microsoft Azure using lightweight software-defined networking. It reduces the complexity of VPN deployments and is designed for businesses of ALL sizes.

 
ora_user2003Commented:
OR U CAN USE md5 AS FOLLOWS ...........


declare
input_string varchar2(20):='DMITRIY1';
key_string varchar2(20):='CODEWORD';
ENCRYPT_STR VARCHAR2(20);

begin



ENCRYPT_STR:=dbms_obfuscation_toolkit.MD5(
INPUT_STRING => INPUT_STRING);
      dbms_output.put_line(' Encrypted string is ' ||
                   encrypt_str);

end ;
/
0
 
schwertnerCommented:
Security Table
First we must build a table to hold the security information:
CREATE TABLE app_users (
  id        NUMBER(10)    NOT NULL,
  username  VARCHAR2(30)  NOT NULL,
  password  VARCHAR2(16)  NOT NULL
)
/

ALTER TABLE app_users ADD (
  CONSTRAINT app_users_pk PRIMARY KEY (id)
)
/

ALTER TABLE app_users ADD (
  CONSTRAINT app_users_uk UNIQUE (username)
)
/

CREATE SEQUENCE app_users_seq
/
Security Package
Next we create the package that contains the specification of the security code:
CREATE OR REPLACE PACKAGE app_user_security AS

  FUNCTION get_hash (p_username  IN  VARCHAR2,
                     p_password  IN  VARCHAR2)
    RETURN VARCHAR2;
   
  PROCEDURE add_user (p_username  IN  VARCHAR2,
                      p_password  IN  VARCHAR2);

  PROCEDURE change_password (p_username      IN  VARCHAR2,
                             p_old_password  IN  VARCHAR2,
                             p_new_password  IN  VARCHAR2);

  PROCEDURE valid_user (p_username  IN  VARCHAR2,
                        p_password  IN  VARCHAR2);

  FUNCTION valid_user (p_username  IN  VARCHAR2,
                       p_password  IN  VARCHAR2)
    RETURN BOOLEAN;

END;
/
We then create the package body to define the actual operations:
CREATE OR REPLACE PACKAGE BODY app_user_security AS

  FUNCTION get_hash (p_username  IN  VARCHAR2,
                     p_password  IN  VARCHAR2)
    RETURN VARCHAR2 AS
  BEGIN
    RETURN DBMS_OBFUSCATION_TOOLKIT.MD5(
      input_string => UPPER(p_username) || '/' || UPPER(p_password));
  END;

  PROCEDURE add_user (p_username  IN  VARCHAR2,
                      p_password  IN  VARCHAR2) AS
  BEGIN
    INSERT INTO app_users (
      id,
      username,
      password
    )
    VALUES (
      app_users_seq.NEXTVAL,
      UPPER(p_username),
      get_hash(p_username, p_password)
    );
   
    COMMIT;
  END;
   
  PROCEDURE change_password (p_username      IN  VARCHAR2,
                             p_old_password  IN  VARCHAR2,
                             p_new_password  IN  VARCHAR2) AS
    v_rowid  ROWID;
  BEGIN
    SELECT rowid
    INTO   v_rowid
    FROM   app_users
    WHERE  username = UPPER(p_username)
    AND    password = get_hash(p_username, p_old_password)
    FOR UPDATE;
   
    UPDATE app_users
    SET    password = get_hash(p_username, p_new_password)
    WHERE  rowid    = v_rowid;
   
    COMMIT;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      RAISE_APPLICATION_ERROR(-20000, 'Invalid username/password.');
  END;

  PROCEDURE valid_user (p_username  IN  VARCHAR2,
                        p_password  IN  VARCHAR2) AS
    v_dummy  VARCHAR2(1);
  BEGIN
    SELECT '1'
    INTO   v_dummy
    FROM   app_users
    WHERE  username = UPPER(p_username)
    AND    password = get_hash(p_username, p_password);
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      RAISE_APPLICATION_ERROR(-20000, 'Invalid username/password.');
  END;
 
  FUNCTION valid_user (p_username  IN  VARCHAR2,
                       p_password  IN  VARCHAR2)
    RETURN BOOLEAN AS
  BEGIN
    valid_user(p_username, p_password);
    RETURN TRUE;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN FALSE;
  END;
 
END;
/
The overloads of VALID_USER allow the security check to be performed in a different manner.

The GET_HASH function is used to hash the combination of the username and password. It always returns a VARCHAR2(16) regardless of the length of the input parameters. This level of compression means that the hash value may not be unique, hence the unique constraint on the USERNAME column.

The DBMS_UTILITY.GET_HASH_VALUE function could be used to replace the DBMS_OBFUSCATION_TOOLKIT.MD5 function, but the hashing algorithm of the former is not garaunteed to stay constant between database versions.
Testing
First we create a new user:
SQL> exec app_user_security.add_user('tim','hall');

PL/SQL procedure successfully completed.

SQL> select * from app_users;

        ID USERNAME                       PASSWORD
---------- ------------------------------ ----------------
         1 TIM                            [w®44Z䪿¿8fE�pre>
Next we check the VALID_USER procedure:
SQL> EXEC app_user_security.valid_user('tim','hall');

PL/SQL procedure successfully completed.

SQL> EXEC app_user_security.valid_user('tim','abcd');
BEGIN app_user_security.valid_user('tim','hall1'); END;

*
ERROR at line 1:
ORA-20000: Invalid username/password.
ORA-06512: at "W2K1.APP_USER_SECURITY", line 37
ORA-06512: at line 1
Next we check the VALID_USER function:
SQL> SET SERVEROUTPUT ON
SQL> BEGIN
  2    IF app_user_security.valid_user('tim','hall') TH
  3      DBMS_OUTPUT.PUT_LINE('TRUE');
  4    ELSE
  5      DBMS_OUTPUT.PUT_LINE('FALSE');
  6    END IF;
  7  END;
  8  /
TRUE

PL/SQL procedure successfully completed.

SQL> BEGIN
  2    IF app_user_security.valid_user('tim','abcd') T
  3      DBMS_OUTPUT.PUT_LINE('TRUE');
  4    ELSE
  5      DBMS_OUTPUT.PUT_LINE('FALSE');
  6    END IF;
  7  END;
  8  /
FALSE

PL/SQL procedure successfully completed.

SQL>
Finally we check the CHANGE_PASSWORD procedure:
SQL> exec app_user_security.change_password('tim','hall','hall1');

PL/SQL procedure successfully completed.

SQL> exec app_user_security.change_password('tim','abcd','abcd1');
BEGIN app_user_security.change_password('tim','abcd','abcd1'); END;

*
ERROR at line 1:
ORA-20000: Invalid username/password.
ORA-06512: at "W2K1.APP_USER_SECURITY", line 47
ORA-06512: at line 1

SQL>
0
 
DmitriyAuthor Commented:
Here is what I have so far.

I decided to go with the application side encryption. For application side, I have the following code ready:
.................................
// Code for adding an encrypted password to a user table:

String sql = "insert into user_table (user_name, password) values (?, ?)";
pstmt = myConnection.prepareStatement(sql);

u_name = <some string here>;
ui_password = new String(encrypt (ui_password));
pstmt.setString(1, u_name);
pstmt.setString(2, ui_password) ;
resultStat = pstmt.executeUpdate();
// I don't include some extra code for declaration and closing of DB connections since it's irrelevant.
................
//Code to compare the provided password and the password that was stored in the DB:

          String encryptedPass = new String(encrypt(password));

          System.out.println("Encrypted:"+encryptedPass+"|");
          System.out.println("DB passwd:"+ui_password+"|");
               
          //if(userId.equals(ui_username.trim()) && encryptedPass.equals(ui_password))
          if(userId.equals(ui_username.trim()) && password.equals(ui_password))
                     // login here
.................
// Encryption
      static byte[] encrypt(String x)   throws Exception      
      {
            MessageDigest d = null;
          d = MessageDigest.getInstance("md5");
          d.reset();
          d.update(x.getBytes());
          return d.digest();
      
      }
...................

There seems to be a problem with the code.  When I do the comparison, the strings that are printed out for password are different.  Thus the string comparison would return false and user is unable to log in.  I don't know why the SAME encrypted string is different in database and application.  When I do a printout of the user typed password and DB password,  encrypted characters are printed out.  I notice that one or two characters are different.  Am I doing something wrong?






                   
0
 
DmitriyAuthor Commented:
Gentlement,
I found everything I needed on this site.

http://www.devarticles.com/c/a/Java/Password-Encryption-Rationale-and-Java-Example

It gave me the code to hash and store the password.

SMartinHamburg, your first link put me in the right direction.  Thanks everyone.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now