Apache2-API
view release on metacpan or search on metacpan
lib/Apache2/API.pm view on Meta::CPAN
# try-catch
eval
{
$ctx->add( $passwd, $magic, $salt );
};
if( $@ )
{
return( $self->error( "Error adding string to create MD5 hash: $@" ) );
}
# 2) alternate sum: md5(password + salt + password)
my $alt = Digest::MD5->new;
eval
{
$alt->add( $passwd, $salt, $passwd );
};
if( $@ )
{
return( $self->error( "Error adding string to create MD5 hash: $@" ) );
}
# 16 bytes
my $alt_result = $alt->digest;
# 3) append to ctx as many full 16-byte blocks of alt_result
my $plen = length( $passwd );
for( my $i = $plen; $i > 0; $i -= 16 )
{
eval
{
$ctx->add( substr( $alt_result, 0, $i < 16 ? $i : 16 ) );
};
if( $@ )
{
return( $self->error( "Error adding string to create MD5 hash: $@" ) );
}
}
# 4) mix in bytes based on bits of password length
for( my $i = $plen; $i > 0; $i >>= 1 )
{
eval
{
if( $i & 1 )
{
$ctx->add( pack( 'C', 0 ) );
}
else
{
$ctx->add( substr( $passwd, 0, 1 ) );
}
};
if( $@ )
{
return( $self->error( "Error adding string to create MD5 hash: $@" ) );
}
}
# 16 bytes
my $final = $ctx->digest;
# 5) 1000 iterations "rounds"
for( my $i = 0; $i < 1000; $i++ )
{
my $t = Digest::MD5->new;
eval
{
if( $i & 1 )
{
$t->add( $passwd );
}
else
{
$t->add( $final );
}
if( $i % 3 )
{
$t->add( $salt );
}
if( $i % 7 )
{
$t->add( $passwd );
}
if( $i & 1 )
{
$t->add( $final );
}
else
{
$t->add( $passwd );
}
};
if( $@ )
{
return( $self->error( "Error adding string to create MD5 hash: $@" ) );
}
$final = $t->digest;
}
# 6) rearrange final bytes and base64-like encode (crypt's 64-char set)
my @b = unpack( 'C16', $final );
my $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
my $encoded = '';
$encoded .= $self->_to64( ( $b[0] << 16 ) | ( $b[6] << 8 ) | $b[12], 4, $itoa64 );
$encoded .= $self->_to64( ( $b[1] << 16 ) | ( $b[7] << 8 ) | $b[13], 4, $itoa64 );
$encoded .= $self->_to64( ( $b[2] << 16 ) | ( $b[8] << 8 ) | $b[14], 4, $itoa64 );
$encoded .= $self->_to64( ( $b[3] << 16 ) | ( $b[9] << 8 ) | $b[15], 4, $itoa64 );
$encoded .= $self->_to64( ( $b[4] << 16 ) | ( $b[10] << 8 ) | $b[5], 4, $itoa64 );
$encoded .= $self->_to64( $b[11], 2, $itoa64 );
return( $magic . $salt . '$' . $encoded );
}
sub make_sha256 { return( shift->_make_sha_crypt( 5, @_ ) ); }
sub make_sha512 { return( shift->_make_sha_crypt( 6, @_ ) ); }
( run in 1.196 second using v1.01-cache-2.11-cpan-96521ef73a4 )