PHP: çöp dize mcrypt mangles başlangıcı

2 Cevap php

Ben serverside güçlü şifreleme orta gerekir, bu yüzden ben PHP ile mcrypt kullanmak düşündüm. Benim özgün dize başında aşağıdaki işlevleri kullanıyorsanız şifre çözme sonra ikili çöp dönüşür. ) Belgelerin, MCRYPT_ENCRYPT göre (blok boyutunu maç için yeterli karakterleri yastıklı olmalıdır (Bu additional çöp yerine benim dize altered. Ekli alma olağan sorun değildir) Seçilen algoritmanın ama çalışmıyor sanıyorum.

Manuel 128 bit Rijndael (16 bayt) blok boyutuna ben ped onu Ancak, o da çalışmıyor. Ben iş için bu alabilirsiniz tek yolu (büyük olasılıkla) garbaged bloğunu kapsayacak ve bu string ve benim verileri arasında "DATA #" gibi bilinen bir önek eklemek için yeterince uzun bazı dize prepending gereğidir. Şifre çözme sonra blok kısmen parçalanmış olmuştur ama bu benim önek ve bundan sonra tüm verileri doğru şekilde deşifre edilmiştir.

$GLOBALS['encryptionmarker'] = 'DATA#';

function encrypt($plain, $key) {
    /*
    // workaround because beginning of decrypted string is being mangled
    // so we simply prefix with some text plus marker
    $prefix = str_pad('', 128, '#', STR_PAD_RIGHT).$GLOBALS['encryptionmarker'];
    $plain = $prefix.$plain;
    */

    $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $plain, MCRYPT_MODE_CFB,
        mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB),
        MCRYPT_DEV_URANDOM));

    return $encrypted;
}

function decrypt($encrypted, $key) {
    $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, MCRYPT_MODE_CFB,
        mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB),
        MCRYPT_DEV_URANDOM));

    /*
    // workaround: remove garbage
    $pos = strpos($decrypted, $GLOBALS['encryptionmarker']);
    $decrypted = trim(substr($decrypted, $pos + strlen($GLOBALS['encryptionmarker'])));
    */

    return $decrypted;
}

Ne benim fonksiyonları nesi var? Neden (ben kirli bir çözüm düşünün, ben bunu düzeltmek istiyorum) böyle benim veri önek var?

Şifrelenmiş verileri depolamak sorun değildir; Aynı hataları bir veritabanı sonuçları saklayarak olmadan hemen sonra şifreleme şifresini.

2 Cevap

Senin sorunun alıcı tarafta yeni, farklı, rasgele IV üreten olmasıdır. Bu gördüğünüz gibi, çalışmaz.

Alıcı gönderen kullanılan IV bilmesi gerekir; böylece şifreli veri ile birlikte gönderebilirsiniz ve mcrypt_decrypt() onu geçmek zorunda.

Ayrıca mesajın üzerinde bir HMAC oluşturmak için bir anahtar (şifreleme anahtarına farklı bir tuş) ile mhash() kullanmak, ve alıcı tarafta kontrol gerektiğini unutmayın. Bunu yapmazsanız, bir man-in-the-orta trivially bunu tespit olmadan mesajın parçaları değiştirebilirsiniz.

En-ve şifre çözme aynı IV kullanın. IV, paylaşılan sır değil, ancak paylaşılmasına sahiptir. Sen danışabilir Wikipedia: IV

$IV = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB),
      MCRYPT_DEV_URANDOM));

IV ONCE transfer edilmelidir. Her paket için IV değerini artırmak isteyebilirsiniz. Ancak bu, bağımsız bir şekilde her iki tarafına da yapılabilir.