Crypt-SmbHash
view release on metacpan or search on metacpan
use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION);
@ISA = qw(Exporter);
$VERSION = '0.12';
@EXPORT = qw( ntlmgen );
# The mdfour function is available for exporting if they really want
# it =)
@EXPORT_OK = qw( lmhash nthash ntlmgen mdfour smbhash E_P24 E_P21 SMBNTencrypt );
# Works out if local system has Digest::MD4 and Encode
my $HaveDigestMD4;
my $HaveUnicode;
BEGIN {
$HaveDigestMD4 = 0;
$HaveUnicode = 0;
if ( eval "require 'Digest/MD4.pm';" ) {
$HaveDigestMD4 = 1;
}
if (eval "require Encode;") {
import Encode;
$HaveUnicode = 1;
}
}
# lmhash PASSWORD
# Generates lanman password hash for a given password, returns the hash
#
# Extracted and ported from SAMBA/source/libsmb/smbencrypt.c:nt_lm_owf_gen
sub lmhash($;$) {
my ( $pass, $pwenc ) = @_;
my ( @p16 );
$pass = "" unless defined($pass);
$pass = uc($pass);
if (!$HaveUnicode) {
if (defined($pwenc)) {
croak "Encode module not found: no encoding support";
}
}
else {
$pwenc = "iso-8859-1" unless defined($pwenc);
$pass = encode($pwenc,$pass);
}
$pass = substr($pass,0,14);
@p16 = E_P16($pass);
return join("", map {sprintf("%02X",$_);} @p16);
}
# nthash PASSWORD
# Generates nt md4 password hash for a given password, returns the hash
#
# Extracted and ported from SAMBA/source/libsmb/smbencrypt.c:nt_lm_owf_gen
sub nthash($) {
my ( $pass ) = @_;
my ( $hex );
my ( $digest );
$pass = substr(defined($pass)?$pass:"",0,128);
if (!$HaveUnicode) {
# No unicode support: do a really broken to ucs2 convert
$pass =~ s/(.)/$1\000/sg;
}
else {
$pass = encode('ucs2', $pass);
$pass = pack("v*", unpack("n*",$pass));
}
$hex = "";
if ( $HaveDigestMD4 ) {
eval {
$digest = new Digest::MD4;
$digest->reset();
$digest->add($pass);
$hex = $digest->hexdigest();
$hex =~ tr/a-z/A-Z/;
};
$HaveDigestMD4 = 0 unless ( $hex );
}
$hex = sprintf("%02X"x16,mdfour($pass)) unless ( $hex );
return $hex;
}
# ntlmgen PASSWORD, LMHASH, NTHASH
# Generate lanman and nt md4 password hash for given password, and assigns
# values to arguments. Combined function of lmhash and nthash
sub ntlmgen {
my ( $nthash, $lmhash );
$nthash = nthash($_[0]);
$lmhash = lmhash($_[0]);
if ( $#_ == 2 ) {
$_[1] = $lmhash;
$_[2] = $nthash;
}
return ( $lmhash, $nthash );
}
# Support functions
# Ported from SAMBA/source/lib/md4.c:F,G and H respectfully
sub F { my ( $X, $Y, $Z ) = @_; return ($X&$Y) | ((~$X)&$Z); }
sub G { my ( $X, $Y, $Z) = @_; return ($X&$Y) | ($X&$Z) | ($Y&$Z); }
sub H { my ($X, $Y, $Z) = @_; return $X^$Y^$Z; }
# Needed? because perl seems to choke on overflowing when doing bitwise
# operations on numbers larger than 32 bits. Well, it did on my machine =)
sub add32 {
my ( @v ) = @_;
my ( $ret, @sum );
foreach ( @v ) {
$_ = [ ($_&0xffff0000)>>16, ($_&0xffff) ];
}
@sum = ();
foreach ( @v ) {
$sum[0] += $_->[0];
$sum[1] += $_->[1];
}
$sum[0] += ($sum[1]&0xffff0000)>>16;
$sum[1] &= 0xffff;
$sum[0] &= 0xffff;
$ret = ($sum[0]<<16) | $sum[1];
return $ret;
}
( run in 0.616 second using v1.01-cache-2.11-cpan-39bf76dae61 )