2013-02-27 54 views
1

如何在Perl中處理Crypt :: Blowfish的非ANSI字符?如何在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: [email protected]") 
    for (@chars); 

回答

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)); 
2

許多Crypt :: *模塊是塊加密算法。所以,他們只能使用固定長度的塊。由於'§'是一個UTF8字符,它實際上包含多於一個字節,這就是爲什麼你的代碼失敗。另一個問題是您使用use utf8編譯指示,這意味着utf8常量字符串將使用「utf8標誌」創建。這可能會導致二進制算法發生重大變化,如加密。

我建議你使用Crypt::CBC模塊(在CPAN上檢查它);並且在加密之前刪除utf8標誌:utf8::encode($_);