Tie-EncryptedHash
view release on metacpan or search on metacpan
lib/Tie/EncryptedHash.pm view on Meta::CPAN
return undef unless $auth;
return $ptext;
# PUBLIC FIELD
} elsif ( $key =~ m/([^:]*)$/ || $key =~ m/.*?::([^:]*)/ ) {
$self->{$1} = $value if $value;
delete $$self{$1} if $delete;
return $self->{$1} if $self->{$1};
return undef;
}
}
sub encrypt { # ($plaintext, $password, $cipher)
$_[0] = qq{REF }. Data::Dumper->new([$_[0]])->Indent(0)->Terse(0)->Purity(1)->Dumpxs if ref $_[0];
return qq{$_[2] } . md5_base64($_[0]) .qq{ } .
Crypt::CBC->new($_[1],$_[2])->encrypt_hex($_[0])
}
sub decrypt { # ($cipher $md5sum $ciphertext, $password)
return undef unless $_[1];
my ($m, $d, $c) = split /\s/,$_[0];
my $ptext = Crypt::CBC->new($_[1],$m)->decrypt_hex($c);
my $check = md5_base64($ptext);
if ( $d eq $check ) {
if ($ptext =~ /^REF (.*)/is) {
my ($VAR1,$VAR2,$VAR3,$VAR4,$VAR5,$VAR6,$VAR7,$VAR8);
return eval qq{$1};
}
return $ptext;
}
}
sub verify { # ($self, $key)
my ($self, $key) = splice @_,0,2;
# debug ("$self->{__scaffolding}{$key}, $self->{__password}, $self->{$key}");
return 1 unless $key =~ m:^_:;
return 1 unless exists $self->{$key};
return undef if ref $self->{$key} && ($self->{__scaffolding}{$key} ne
$self->{__password});
my $ptext = decrypt($self->{$key}, $self->{__password});
return $ptext if $ptext;
}
sub each { CORE::each %{$_[0]} }
sub keys { CORE::keys %{$_[0]} }
sub values { CORE::values %{$_[0]} }
sub exists { CORE::exists $_[0]->{$_[1]} }
sub TIEHASH # ($class, @args)
{
my $class = ref($_[0]) || $_[0];
my $self = bless {}, $class;
$self->{__password} = $_[1] if $_[1];
$self->{__cipher} = $_[2] || qq{Blowfish};
return $self;
}
sub FETCH # ($self, $key)
{
my ($self, $key) = @_;
my $entry = _access($self,$key,(caller)[0..1]);
return $entry if $entry;
}
sub STORE # ($self, $key, $value)
{
my ($self, $key, $value) = @_;
my $entry = _access($self,$key,(caller)[0..1],$value);
return $entry if $entry;
}
sub DELETE # ($self, $key)
{
my ($self, $key) = @_;
return _access($self,$key,(caller)[0..1],'',1);
}
sub CLEAR # ($self)
{
my ($self) = @_;
return undef if grep { ! $self->verify($_) }
grep { ! /__/ } CORE::keys %{$self};
%{$self} = ();
}
sub EXISTS # ($self, $key)
{
my ($self, $key) = @_;
my @context = (caller)[0..1];
return _access($self,$key,@context) ? 1 : '';
}
sub FIRSTKEY # ($self)
{
my ($self) = @_;
CORE::keys %{$self};
goto &NEXTKEY;
}
sub NEXTKEY # ($self)
{
my $self = $_[0]; my $key;
my @context = (caller)[0..1];
while (defined($key = CORE::each %{$self})) {
last if eval { _access($self,$key,@context) }
}
return $key;
}
sub DESTROY # ($self)
{
}
1;
__END__
=head1 NAME
Tie::EncryptedHash - Hashes (and objects based on hashes) with encrypting fields.
=head1 SYNOPSIS
use Tie::EncryptedHash;
my %s = ();
tie %s, Tie::EncryptedHash, 'passwd';
$s{foo} = "plaintext"; # Normal field, stored in plaintext.
print $s{foo}; # (plaintext)
$s{_bar} = "signature"; # Fieldnames that begin in single
# underscore are encrypted.
print $s{_bar}; # (signature) Though, while the password
# is set, they behave like normal fields.
delete $s{__password}; # Delete password to disable access
# to encrypting fields.
print $s{_bar}; # (Blowfish NuRVFIr8UCAJu5AWY0w...)
$s{__password} = 'passwd'; # Restore password to gain access.
print $s{_bar}; # (signature)
$s{_baz}{a}{b} = 42; # Refs are fine, we encrypt them too.
=head1 DESCRIPTION
Tie::EncryptedHash augments Perl hash semantics to build secure, encrypting
containers of data. Tie::EncryptedHash introduces special hash fields that
are coupled with encrypt/decrypt routines to encrypt assignments at STORE()
and decrypt retrievals at FETCH(). By design, I<encrypting fields> are
associated with keys that begin in single underscore. The remaining
keyspace is used for accessing normal hash fields, which are retained
without modification.
While the password is set, a Tie::EncryptedHash behaves exactly like a
standard Perl hash. This is its I<transparent mode> of access. Encrypting
and normal fields are identical in this mode. When password is deleted,
encrypting fields are accessible only as ciphertext. This is
Tie::EncryptedHash's I<opaque mode> of access, optimized for serialization.
Encryption is done with Crypt::CBC(3) which encrypts in the cipher block
chaining mode with Blowfish, DES or IDEA. Tie::EncryptedHash uses Blowfish
( run in 0.706 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )