NSIS ve PHP arasındaki Blowfish şifreli mesajlar

1 Cevap php

Ben üzerinde çalışıyorum bir proje için, ben NSIS ve PHP arasında uyumlu bir şekilde Blowfish kullanarak bir dize şifrelemek ve şifresini çözmek gerekir.

Şu anda ben NSIS ve PHP ile mcrypt kütüphane için Blowfish++ plugin kullanıyorum. Sorun ben ikisini aynı çıktıyı almak değil, olduğunu.

En NSIS Blowfish + + eklentisi ile başlayalım. Temelde API:

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

blowfish::encrypt "test@test.com***" "MTIzNDU2Nzg="
Pop $0 ; 0 on success, 1 on failure
Pop $1 ; encrypted message on success, error message on failure

Orada vb CBC, ECB, CFB, olsun hiç bahsedilmemesi ve ben mostly undocumented source okuyarak söylemek mümkün Blowfish'ten yeterince aşina değilim. Ben PHP docs for mcrypt ECB bir IV ihtiyacı olmadığını söylüyor çünkü ECB varsayıyorum.

Ben de Blowfish + + eklenti Base64 (ben neden emin değilim) ikinci argüman şifrelemek deşifre olacağı kaynak kodunu okuyarak öğrendim. Ayrıca Base64 kodlanmış dize döndürür.

Şeyler PHP tarafında için, temelde şifrelemek için bu kodu kullanıyorum:

$plainText = "test@test.com***";
$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);

Ben bütün bunları yapmak Ancak, ben her gelen şu çıktıyı alıyorum:

NSIS: GyCyBcUE0s5gqVDshVUB8w==
PHP:  BQdlPd19zEkX5KT9tnF8Ng==

Ben yanlış ne yapıyorum? NSIS eklenti ECB kullanarak değil mi? Değilse, o IV var ne için kullanıyor?

1 Cevap

Tamam, ben bu kod aracılığıyla gitti ve sonuçları çoğaltılamaz ettik. NSIS is ECB kullanarak - Sorun şifre mod değildir. Sorun NSIS Blowfish kodu broken little-endian makinelerde sadece olmasıdır.

Blowfish algoritması iki 32-bit işaretsiz tamsayılar üzerinde çalışır. 64 bit şifresiz ya da şifreli blok ve bu iki tamsayılar arasında dönüştürmek için, blok iki büyük Endian tamsayılar olarak yorumlanabilir gerekiyordu. NSIS Blowfish eklentisi yerine konak bayt sırayla bunları yorumlayarak - bu yüzden (x86) gibi küçük-endian bilgisayarlar üzerinde doğru olanı yapmak için başarısız olur. Bu kendisi ile birlikte çalışan demektir, ama hakiki Blowfish uygulamaları ile (gibi mcrypt).

Ben Blowfish + + bunu doğru olanı yapmak yapmak için yamalı ettik - modifiye Blowfish::Encrypt ve Blowfish::Decrypt aşağıda, ve yeni sürümü blowfish.cpp {[olduğunu (3)]}.

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;
}