FAQ
Hello,

I have to calculate a hash of username and password in perl.
The calculation should be done this way:

1. Concatenate the username and the password to produce a plaintext string;
2. Convert the plaintext string to uppercase characters;
3. Convert the plaintext string to multi-byte storage format; ASCII
characters have the
high byte set to 0x00;
4. Encrypt the plaintext string (padded with 0s if necessary to the next
even block length)
using the DES algorithm in cipher block chaining (CBC) mode with a fixed
key value of
0x0123456789ABCDEF;
5. Encrypt the plaintext string again with DES-CBC, but using the last
block of the output
of the previous step (ignoring parity bits) as the encryption key. The
last block of the
output is converted into a printable string to produce the password hash
value.

Is it possible to implement this in perl ?
Is the Crypt-DES Module on CPAN the right module and how can I convert
standard string to Multibyte storage ( UTF-16 ? )
An example ist

User: example
password: test
hash: BDA63848A8C31752

I don't need this script to hack anything, we would like to modify oru
oracle paasword from a webfrontend.

Thanks
Andreas

Search Discussions

  • Martin Barth at Apr 27, 2007 at 12:59 pm
    Hi

    On Fri, 27 Apr 2007 11:33:47 +0200
    Andreas Moroder wrote:
    Hello,

    I have to calculate a hash of username and password in perl.
    The calculation should be done this way:
    first the easy stuff, I think you already know that answers to that:
    1. Concatenate the username and the password to produce a plaintext string;
    $username . $password;
    2. Convert the plaintext string to uppercase characters;
    uc();

    3. Convert the plaintext string to multi-byte storage format; ASCII
    characters have the
    high byte set to 0x00;
    I am not sure, but i think that could help you:
    http://search.cpan.org/~dankogai/Encode-2.20/
    4. Encrypt the plaintext string (padded with 0s if necessary to the next
    even block length)
    using the DES algorithm in cipher block chaining (CBC) mode with a fixed
    key value of
    0x0123456789ABCDEF;
    hava a look at:
    http://search.cpan.org/~dparis/Crypt-DES-2.05/DES.pm#NOTES
    they say that the Encryption is done by 8byte blockes.
    your key is 8byte long, that sounds quite good :)
    5. Encrypt the plaintext string again with DES-CBC, but using the last
    block of the output
    of the previous step (ignoring parity bits) as the encryption key. The
    last block of the
    output is converted into a printable string to produce the password hash
    value.

    Is it possible to implement this in perl ?
    It should work :)

    HTH Martin
  • Zentara at Apr 27, 2007 at 2:14 pm

    On Fri, 27 Apr 2007 11:33:47 +0200, andreas.moroder@sb-brixen.it (Andreas Moroder) wrote:

    Hello,

    I have to calculate a hash of username and password in perl.
    The calculation should be done this way:

    1. Concatenate the username and the password to produce a plaintext string;
    2. Convert the plaintext string to uppercase characters;
    3. Convert the plaintext string to multi-byte storage format; ASCII
    characters have the
    high byte set to 0x00;
    4. Encrypt the plaintext string (padded with 0s if necessary to the next
    even block length)
    using the DES algorithm in cipher block chaining (CBC) mode with a fixed
    key value of
    0x0123456789ABCDEF;
    5. Encrypt the plaintext string again with DES-CBC, but using the last
    block of the output
    of the previous step (ignoring parity bits) as the encryption key. The
    last block of the
    output is converted into a printable string to produce the password hash
    value.

    Is it possible to implement this in perl ?
    Is the Crypt-DES Module on CPAN the right module and how can I convert
    standard string to Multibyte storage ( UTF-16 ? )
    An example ist

    User: example
    password: test
    hash: BDA63848A8C31752

    I don't need this script to hack anything, we would like to modify oru
    oracle paasword from a webfrontend.

    Thanks
    Andreas
    I'm a bit unclear about step 5, but it should be doable in Perl once
    you determine the EXACT steps you need to take. Here are some tips
    to maybe get you through the first four steps.
    This my be far off from what Oracle needs, but it seems to work
    for your first 4 steps. Some questions remain, like do you need a salt?
    What do you use to convert back to plaintext hash? Base64encode?
    What does "ignore parity bits" mean?

    You may want to ask this on http://perlmonks.org, where more
    saavy encryption and Oracle monks hang out. But make sure you
    can specify the EXACT steps needed. I'm sure it can be done.

    To be honest, I would assume that the Oracle designers have made this
    quite tricky to avoid hacking their passwords.

    #!/usr/bin/perl
    use warnings;
    use strict;
    use Crypt::CBC;
    use Encode;

    my $key = pack("H16", "0123456789ABCDEF");
    my $user = 'example';
    my $password = 'test';

    my $plaintext = uc($user.$password);
    print("$plaintext\n");

    #converted it to bytes via utf-16le (take a look at "perldoc
    perlunicode")
    my $octets = encode("utf-16", $plaintext);
    print "utf16-> $octets\n";

    my $cipher = Crypt::CBC->new(
    -key => $key,
    -cipher => 'DES',
    # -salt => 1,
    );

    my $ciphertext = $cipher->encrypt($octets);
    print("$ciphertext\n");

    my $recovered = $cipher->decrypt($ciphertext);
    print("$recovered\n");

    # step 5 I'm not sure of. What do you mean by
    # encrypt plaintext again, ignoring parity bits,
    # and what do you want to use to convert it to
    # plaintext... probably base64encoding?

    __END__





    --
    I'm not really a human, but I play one on earth.
    http://zentara.net/japh.html
  • Andreas Moroder at Apr 30, 2007 at 10:49 am
    Hello,

    I got this steps from
    http://www.ecuoug.org/papers/OraclePasswordAlgorithm.pdf
    I'm a bit unclear about step 5, but it should be doable in Perl once
    you determine the EXACT steps you need to take. Here are some tips
    to maybe get you through the first four steps.
    This my be far off from what Oracle needs, but it seems to work
    for your first 4 steps. Some questions remain, like do you need a salt?
    What do you use to convert back to plaintext hash? Base64encode?
    What does "ignore parity bits" mean?

    You may want to ask this on http://perlmonks.org, where more
    saavy encryption and Oracle monks hang out. But make sure you
    can specify the EXACT steps needed. I'm sure it can be done.

    To be honest, I would assume that the Oracle designers have made this
    quite tricky to avoid hacking their passwords.
    According to the document this is not true.


    I will try your code later.

    Thank you
    Andreas
  • Zentara at Apr 30, 2007 at 8:47 pm

    On Mon, 30 Apr 2007 12:48:57 +0200, andreas.moroder@sb-brixen.it (Andreas Moroder) wrote:

    To be honest, I would assume that the Oracle designers have made this
    quite tricky to avoid hacking their passwords.
    According to the document this is not true.
    I will try your code later.
    Thank you
    Andreas
    Hi, there seems to be some discrepancies between the 2 explanations of
    the steps to take. Maybe I'm misunderstanding it all. (probably)

    Anyways, here is a quick try I made. It dosn't work right I'm sure, but
    there are some routines in there that may speed up your attempts at
    a script. I would ask this on perlmonks.org where the REAL perl brains
    are.... I'm just an amateur.

    I'm still unclear about the stripping the 8th bit thing.
    Also when they say to convert the string to utf16, maybe they mean
    char-by-char, instead of a whole string conversion?

    This is blowin my mind. :-)
    Good Luck.

    #!/usr/bin/perl
    use warnings;
    use strict;
    use Crypt::CBC;
    use Encode;

    =head1
    I have to calculate a hash of username and password in perl.
    The calculation should be done this way:

    1. Concatenate the username and the password to produce a plaintext
    string;
    2. Convert the plaintext string to uppercase characters;
    3. Convert the plaintext string to multi-byte storage format; ASCII
    characters have the
    high byte set to 0x00;
    4. Encrypt the plaintext string (padded with 0s if necessary to the next
    even block length)
    using the DES algorithm in cipher block chaining (CBC) mode with a fixed
    key value of
    0x0123456789ABCDEF;
    5. Encrypt the plaintext string again with DES-CBC, but using the last
    block of the output
    of the previous step (ignoring parity bits) as the encryption key. The
    last block of the
    output is converted into a printable string to produce the password hash
    value.

    Is it possible to implement this in perl ?
    Is the Crypt-DES Module on CPAN the right module and how can I convert
    standard string to Multibyte storage ( UTF-16 ? )
    An example ist

    User: example
    password: test
    hash: BDA63848A8C31752


    # more detailed explanation

    Dave Trahan wants to know the Oracle password algorithm so
    he can check for weak passwords. When I was the project
    lead for Trusted Oracle I designed the new password algorithm
    that is used in versions 6, 7, and later. I presented the
    details at a Bay Area Trusted System Symposium so I am not
    revealing any information that is not already in the puiblic
    domain. Here are some of the details as I remember them.

    Design Goals:
    1. Must work with all terminals.
    ===> Some terminals do not have lowercase letters, so
    the password algorithm ignores differences between
    upper and lower case!!! The passwords "Tiger"
    and "tiger" map to the same value.

    2. Must support usernames and passwords that include non-ascii
    characters.
    The username and password are converted to
    16 bit per character representation before any processing
    is done. Ascii characters have the high byte zeroed.

    3. If different users have the same password, then the one-way
    hash value (encrypted value) for the passwords will be different.

    4. Long passwords are supported.
    I believe that usernames and passwords can both be 40 chars.

    Implementation:
    1. Upshift password, convert to 16bits per character, and place
    result left justified in an 80 byte array of zeros.

    2. Using DES in cipher block feedback mode compute the CBC checksum for
    the 80 byte password array using a fixed secret password (you can
    find
    it in the code if you look hard enough). The result is used as the
    key for the next step ignoring parity bits to produce the a 56 bit
    key from the CBC.

    3. Upshift password, and convert to 16bits per character, and place
    result left justified in an 80 byte array of zeros.

    4. Using DES in cipher block feedback mode compute the CBC checksum
    for the 80 byte username array using the key generate in step 2.

    5. Convert the CBC checksum from step 4 into a printable string with
    the obvious algorithm.

    --Bob Baldwin
    Director of Development We provide the best solutions
    Los Altos Technologies, Inc. to our customers key security
    bald...
    =cut

    # start test script #################################

    my $key = pack("H16", "0123456789ABCDEF");
    my $user = 'example';
    my $password = 'test';

    my $plaintext = uc($user.$password);
    print("$plaintext\n");

    #converted it to bytes via utf-16 (take a look at "perldoc perlunicode")
    my $octets = encode("utf-16", $plaintext);
    print "utf16-> $octets\n";

    my $cipher = Crypt::CBC->new(
    -key => $key,
    -cipher => 'DES',
    -salt => 1,
    );

    my $ciphertext = $cipher->encrypt($octets);
    print("$ciphertext\n");


    my( $hex ) = unpack( 'H*', $ciphertext );
    print $hex,"\n";
    my $temp = uc(substr($hex,length($hex)-16,16));
    print "\n$temp\n";

    my $key1 = pack("H16", $temp);

    my $cipher1 = Crypt::CBC->new(
    -key => $key1,
    -cipher => 'DES',
    -salt => 1,
    );


    my $ciphertext1 = $cipher1->encrypt($octets);
    print("$ciphertext1\n");
    my( $hex1 ) = unpack( 'H*', $ciphertext1 );
    print $hex1,"\n";

    my $temp1 = uc(substr($hex1,length($hex1)-16,16));
    print "\n$temp1\n";

    __END__


    zentara



    --
    I'm not really a human, but I play one on earth.
    http://zentara.net/japh.html
  • Andreas Moroder at Apr 30, 2007 at 11:40 am

    I'm a bit unclear about step 5, but it should be doable in Perl once
    you determine the EXACT steps you need to take. Here are some tips
    to maybe get you through the first four steps.
    This my be far off from what Oracle needs, but it seems to work
    for your first 4 steps. Some questions remain, like do you need a salt?
    What do you use to convert back to plaintext hash? Base64encode?
    Hello,

    the hash is store d in hexadecimal format.

    Bye
    Andreas
  • Andreas Moroder at Apr 30, 2007 at 11:54 am
    Sorry,

    I know I should write all in one answer ;)

    I think in this place the algorithm is explained better.

    http://groups.google.com/group/comp.databases.oracle/msg/83ae557a977fb6ed?hl=en

    Bye
    Andreas

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupbeginners @
categoriesperl
postedApr 27, '07 at 9:35a
activeApr 30, '07 at 8:47p
posts7
users3
websiteperl.org

People

Translate

site design / logo © 2021 Grokbase