1

我正在尝试在 perl 中创建一个包,它等效于我们在 php 中用于处理数据加密的预先存在的类。

加密类型似乎是 ECB 模式下的 TripleDES,但是我无法使用 Crypt::CBC 或 Crypt::TripleDES 复制生成的密码文本。

我认为问题与填充或密钥格式(二进制与十六进制等)有关,但搜索文档并不能帮助我找到答案。

当前的 PHP 类如下(精简但具有相同的核心功能):

<?php
class Encryption {
    private $encryption_key;
    private $encryption_td;
    private $encryption_iv;

    private function __construct() {
        $this->encryption_key = 'abc123';
        $this->encryption_td = mcrypt_module_open( 'tripledes', '', 'ecb', '' );
        $this->encryption_iv = mcrypt_create_iv ( mcrypt_enc_get_iv_size( $this->encryption_td ), MCRYPT_RAND );

        mcrypt_generic_init( $this->encryption_td, $this->encryption_key, $this->encryption_iv );
    }

    public function __destruct() {
        mcrypt_generic_deinit( $this->encryption_td );
        mcrypt_module_close( $this->encryption_td );
    }   

    public static function instance($key = null, $iv = null, $algorithm = null, $mode = null) {
        static $instance;

        if (! $instance) {
            $instance = new Encryption( $key, $iv, $algorithm, $mode );
        }

        return $instance;
    }

    public function encrypt( $password ) {
        return base64_encode( mcrypt_generic( $this->encryption_td, $password ) );
    }

    public function decrypt( $password ) {
        return trim(mdecrypt_generic( $this->encryption_td, base64_decode( $password ) ) );
    }
}

function decrypt_password( $password ) {
    return Encryption::instance()->decrypt( $password );
}

function encrypt_password( $password ) {
    return Encryption::instance()->encrypt( $password );
}

print encrypt_password( 'wibblewobble123' ) . "\n";
print decrypt_password( encrypt_password( 'wibblewobble123' ) ) . "\n";
?>

我目前的perl包如下:

package Encryption;
use warnings;
use strict;
use MIME::Base64;
use Crypt::TripleDES;

sub new {
    my $class = shift;
    my $self = {};
    $self->{'encryption_key'} = 'abc123';
    $self->{'td'} = Crypt::TripleDES->new();
    bless( $self, $class );
    return $self;
}

sub decrypt {
    my( $self, $encrypted_password ) = @_;
    $encrypted_password = decode_base64( $encrypted_password );
    my $password = $self->{'td'}->decrypt3( $encrypted_password, $self->{'encryption_key'} );
    chomp( $password );
    return $password;
}

sub encrypt {
    my( $self, $password ) = @_;
    my $encrypted_password = $self->{'td'}->encrypt3( $password, $self->{'encryption_key'} );
    $encrypted_password = encode_base64( $encrypted_password );
    chomp( $encrypted_password );
    undef( $password );
    return $encrypted_password;
}

1;

和测试代码:

use warnings;
use strict;

use Encryption;

sub decrypt {
    my $password = shift;
    my $eh = Encryption->new();
    return $eh->decrypt( $password );
}

sub encrypt {
    my $password = shift;
    my $eh = Encryption->new();
    return $eh->encrypt( $password );
}

print encrypt( 'wibblewobble123' ) . "\n";
print decrypt( encrypt( 'wibblewobble123' ) ) . "\n";

每个的输出如下:

php:

xuRt3xxjPO1GUz+DccTVKw==
wibblewobble123

perl:

mmWuKkpvveHvnUsQ2NC6DA==
wibblewobble123

预期的结果是 perl 的加密子例程返回与 php 的加密函数相同的输出,而解密执行相同但相反。

如果 Crypt::TripleDES 是解决这个问题的错误方法,那么我很乐意使用其他东西 - 无论如何,这段代码都会被重新编写成更整洁的东西。

作为旁注,这将需要使用多个密钥长度,因此如果这是一个填充问题,请解释如何根据密钥长度计算正确的填充。

4

0 回答 0