2010-01-28 49 views
1

對於我正在開發的項目,我需要使用Blowfish以跨NSIS和PHP的兼容方式對字符串進行加密和解密。NSIS和PHP之間的Blowfish加密郵件

目前我正在使用Blowfish++ plugin用於NSIS和mcrypt庫與PHP。問題是,我無法讓他們都產生相同的輸出。

讓我們從NSIS Blowfish ++插件開始。基本上API是:

; Second argument needs to be base64 encoded 
; base64_encode("12345678") == "MTIzNDU2Nzg=" 

blowfish::encrypt "[email protected]***" "MTIzNDU2Nzg=" 
Pop $0 ; 0 on success, 1 on failure 
Pop $1 ; encrypted message on success, error message on failure 

有沒有它是否是CBC,ECB,CFB等,提到我不與河豚不夠熟悉,可以通過讀取mostly undocumented source告訴。我認爲這是自PHP docs for mcrypt tells me that ECB doesn't need an IV以來的歐洲央行。

我也通過閱讀Blowfish ++插件將Base64解碼第二個參數進行加密的源代碼(我不知道爲什麼)。它也返回一個Base64編碼的字符串。

對於事物的PHP方面,我基本上使用此代碼加密:

$plainText = "[email protected]***"; 
$cipher = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_ECB, ''); 
$iv = '00000000'; // Show not be used anyway. 
$key = "12345678"; 

$cipherText = ""; 
if (mcrypt_generic_init($cipher, $key, $iv) != -1) 
{ 
    $cipherText = mcrypt_generic($cipher, $plainText); 
    mcrypt_generic_deinit($cipher);   
} 

echo base64_encode($cipherText); 

但是,如果我做這些事情,我得到下面的輸出從每個:

NSIS: GyCyBcUE0s5gqVDshVUB8w== 
PHP: BQdlPd19zEkX5KT9tnF8Ng== 

我做錯了什麼? NSIS插件是否不使用ECB?如果沒有,那麼它的IV是什麼?

回答

11

好的,我已經通過該代碼並重現了您的結果。問題不是密碼模式 - 使用ECB的NSIS 。問題是NSIS Blowfish代碼只是在小端機器上的破碎的

Blowfish算法對兩個32位無符號整數進行操作。爲了在64位明文或密文塊和這兩個整數之間進行轉換,應該將該塊解釋爲兩個Big Endian整數。 NSIS Blowfish插件是以主機字節順序來解釋它們 - 所以它不能在小端主機(如x86)上做正確的事情。這意味着它可以與自己進行互操作,但不會與真正的Blowfish實現(如mcrypt)相互操作。

我修補河豚++爲你讓它做正確的事 - 修改Blowfish::EncryptBlowfish::Decrypt低於,並blowfish.cpp新版本here on Pastebin

void Blowfish::Encrypt(void *Ptr,unsigned int N_Bytes) 
{ 
    unsigned int i; 
    unsigned char *Work; 

    if (N_Bytes%8) 
    { 
      return; 
    } 

    Work = (unsigned char *)Ptr; 

    for (i=0;i<N_Bytes;i+=8) 
    { 
     Word word0, word1; 

     word0.byte.zero = Work[i]; 
     word0.byte.one = Work[i+1]; 
     word0.byte.two = Work[i+2]; 
     word0.byte.three = Work[i+3]; 

     word1.byte.zero = Work[i+4]; 
     word1.byte.one = Work[i+5]; 
     word1.byte.two = Work[i+6]; 
     word1.byte.three = Work[i+7]; 

     BF_En(&word0, &word1); 

     Work[i] = word0.byte.zero; 
     Work[i+1] = word0.byte.one; 
     Work[i+2] = word0.byte.two; 
     Work[i+3] = word0.byte.three; 

     Work[i+4] = word1.byte.zero; 
     Work[i+5] = word1.byte.one; 
     Work[i+6] = word1.byte.two; 
     Work[i+7] = word1.byte.three; 
    } 

    Work = NULL; 
} 

void Blowfish::Decrypt(void *Ptr, unsigned int N_Bytes) 
{ 
    unsigned int i; 
    unsigned char *Work; 

    if (N_Bytes%8) 
    { 
      return; 
    } 

    Work = (unsigned char *)Ptr; 
    for (i=0;i<N_Bytes;i+=8) 
    { 
     Word word0, word1; 

     word0.byte.zero = Work[i]; 
     word0.byte.one = Work[i+1]; 
     word0.byte.two = Work[i+2]; 
     word0.byte.three = Work[i+3]; 

     word1.byte.zero = Work[i+4]; 
     word1.byte.one = Work[i+5]; 
     word1.byte.two = Work[i+6]; 
     word1.byte.three = Work[i+7]; 

     BF_De(&word0, &word1); 

     Work[i] = word0.byte.zero; 
     Work[i+1] = word0.byte.one; 
     Work[i+2] = word0.byte.two; 
     Work[i+3] = word0.byte.three; 

     Work[i+4] = word1.byte.zero; 
     Work[i+5] = word1.byte.one; 
     Work[i+6] = word1.byte.two; 
     Work[i+7] = word1.byte.three; 
    } 

    Work = NULL; 
} 
+1

謝謝caf ...我會把這篇文章鏈接到NSIS插件網站上,以免其他程序員浪費時間使用破損版本。 – cdmckay 2010-01-28 20:30:32

+2

+1真正的努力。 – 2010-01-29 00:42:36