Well That’s Random…

Increasingly we are asked to provide more secure passwords for accounts of all kinds. As I have written previously, because coming up with new ones that meet all complexity requirements can be a real pain, I try to avoid passwords whenever possible in favor of PKE authentication. Sometimes, however, they are unavoidable.

So how secure is “secure”? DISA STIG guidelines state that at a minimum, a secure password should have the following characteristics:

  • A length of at least 15 characters
  • At least one upper case character
  • At least one lower case character
  • At least one number
  • At least one special character

I prefer to take it up a notch, especially with passwords for application accounts for JDBC connection pools and the like. I generally require a minimum of 20 characters, and two each of upper case, lower case, numbers, and special characters. What happens when you need to provide passwords for dozens of accounts across multiple environments that must all be unique, and preferably not too predictable? You get random!

Both the Oracle database and the Linux operating system provide ways to generate random sets of characters which can be exploited to quickly generate fully compliant passwords. For example, the DBMS_RANDOM package in Oracle can be used something like this (example code available for download here):

create or replace package utl_password as

    Name: utl_password

    The utl_password package allows you to generate a random   
    alphanumeric password (with special characters) of the 
    length specified in the input.


  function generate_random (p_length number) return varchar2;

end utl_password;

create or replace package body utl_password as

  function generate_random (p_length number) return varchar2
     my_str   varchar2 (4000);
     /* Build a random alphanumeric string of the length 
        specified in the input */
     for i in 1 .. (p_length-1)
         my_str := my_str || 
                   dbms_random.string (
                       when dbms_random.value (0, 1) < 0.5 
                       then 'l' 
                       else 'x' end,
     end loop;

     /* Replace 12 random alphanumeric characters with 
        special characters */
     my_str := translate (my_str, 
               dbms_random.string ('A', 12),'_+/#)^!&*(%|');

     /* Ensure that our string starts with a character */
     my_str := dbms_random.string('a', 1) || my_str;

     return my_str;
  end generate_random;

end utl_password;

Package UTL_PASSWORD compiled

Elapsed: 00:00:00.281

Package Body UTL_PASSWORD compiled

Elapsed: 00:00:00.051

Once completed, the function can be called like this:

select utl_password.generate_random(20) from dual;


Elapsed: 00:00:00.049
1 rows selected.

And presto! One fully compliant password, ready to use. If by some fluke the password produced isn’t fully compliant, just run the function again.

But what if I need a lot of passwords, all at once? A slight modification of our query produces the desired effect:

select utl_password.generate_random(20) 
  from dual connect by level <= 10;


Elapsed: 00:00:00.005
10 rows selected.

But what if remembering the SQL is too complicated, or I just don’t like to type that much? Not to worry: a quick bash shell script (available here) can do pretty much the same thing.

# mkpwd, version 1
# by Pete Magee

# This script generates a random password of 20 alphanumeric 
# and special characters. It takes the number of passwords  
# to be created as an argument.

# For the number of random passwords specified in the 
# command line
for (( i=1; i<=$1; i++ ))

  # Use the built-in random number generator to determine 
  # which characters to include. Add whatever special 
  # characters you wish to utilize in the template after 
  # "[:alnum:]".
  echo `head -n 10 /dev/urandom | 
        tr -cd "[:alnum:]_!@#$%^&*() " | 
        cut -c '1-20'`

This script is already coded to produce a 20-character password; rather than the length of the password, it accepts the number of passwords to generate:

$ ./mkpasswd 10
J71hN oNpz$J0pIrwVlH
xxUto#TM@kZ_jiI5Mm C
P3xOs1NlX kTv6Mq9gOR

Scripts like these can take an otherwise arduous chore and make it quick and relatively painless. For an extra bit of security – just in case the random generation isn’t quite random enough, check out this post for ensuring that passwords do not contain dictionary words, and this one for securing your new passwords in an Oracle Wallet.

One thought on “Well That’s Random…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.