1

如何在 Perl 中处理 Crypt::Blowfish 的非 ANSI 字符?

以下脚本是用字符集 UTF-8 编写的,仅在§或上失败ö

#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use utf8;
use Crypt::Blowfish;
my $cipher = Crypt::Blowfish->new( pack 'H16', '12345678' );
my @chars = ( 'a', '§', 'ö', '9' );
printf( "%s: %s",
    $_, ( eval { $cipher->encrypt( $_ x 8 ) } ) ? "ok\n" : "fail: $@" )
    for ( @chars );
4

2 回答 2

4

密码适用于流或字节块,但您没有为它提供字节。您正在为其提供 Unicode 应对点。

您需要先将要加密的任何文本序列化为字节,然后才能对其进行加密,也就是说,您需要对文本进行编码。

use Encode qw( encode_utf8 );
my $bytes = encode_utf8($char x 8);

此外,您不应该直接使用Crypt::Blowfish。这将产生弱加密。您想通过Crypt::CBC访问它。这提供了盐渍、链接和填充。

use Crypt::CBC qw( );
use Encode     qw( encode_utf8 decode_utf8 );

my $cipher = Crypt::CBC->new(
   -key    => '... key phrase ...',
   -cipher => 'Blowfish',
);

my $cipher_bytes = $cipher->encrypt(encode_utf8($plain_text));
my $plain_text = decode_utf8($cipher->decrypt($cipher_bytes));
于 2013-02-27T12:48:49.063 回答
2

许多 Crypt::* 模块都是块加密算法。因此,它们只能使用固定长度的块。由于 '§' 是一个 UTF8 字符,它实际上包含超过 1 个字节,这就是你的代码失败的原因。另一个问题是您使用了use utf8编译指示,这意味着将使用“utf8 标志”创建 utf8 常量字符串。这可能会导致二进制算法发生重大变化,例如加密。

我建议你使用Crypt::CBC模块(在 CPAN 上检查);并且,在加密之前删除 utf8 标志:utf8::encode($_);

于 2013-02-27T12:48:18.277 回答