İki yönlü şifreleme: Geri alınabilecek şifreleri saklamam gerekiyor


174

Kullanıcının alabileceği ve görebileceği şifreleri saklayacak bir uygulama oluşturuyorum. Parolalar bir donanım aygıtı içindir, bu nedenle karmaları kontrol etmek söz konusu değildir.

Bilmem gerekenler:

  1. PHP'de bir şifreyi nasıl şifreler ve şifresini çözerim?

  2. Şifreleri şifrelemek için en güvenli algoritma nedir?

  3. Özel anahtarı nerede saklayabilirim?

  4. Özel anahtarı saklamak yerine, şifreleri çözülmüş bir şifreye ihtiyaç duyduklarında kullanıcıların özel anahtarı girmelerini istemek iyi bir fikir mi? (Bu uygulamanın kullanıcılarına güvenilebilir)

  5. Şifre hangi yollarla çalınabilir ve şifresi çözülebilir? Nelerden haberdar olmam gerekir?


1
Not: Libsodium artık PHP çekirdeğinde> = 7.2 olarak derlenmiştir. Kullanımdan kaldırılan ve kaldırılan mcrypt'in aksine modern yöntemlerle dolu olduğu için bu şimdi "git" çözümü olacaktır.
Sergi

Yanıtlar:


212

Şahsen ben mcryptyayınlanan diğerleri gibi kullanırdım . Ama dikkat edilmesi gereken çok şey var ...

  1. PHP'de bir şifreyi nasıl şifreler ve şifresini çözerim?

    Sizin için her şeyi halleden güçlü bir sınıf için aşağıya bakın:

  2. Şifreleri şifrelemek için en güvenli algoritma nedir?

    en güvenli ? herhangi biri. Şifreleyecekseniz en güvenli yöntem, bilginin açığa çıkması güvenlik açıklarına (XSS, uzaktan dahil etme vb.) Karşı korunmaktır. Çıkarsa, saldırgan sonunda şifrelemeyi kırabilir (hiçbir şifreleme anahtar olmadan% 100 geri alınamaz - @NullUserException bunun tamamen doğru olmadığına işaret eder. OneTimePad gibi kırılması imkansız olan bazı şifreleme şemaları vardır ) .

  3. Özel anahtarı nerede saklayabilirim?

    Yapacağım şey 3 anahtar kullanmak. Biri kullanıcı tarafından sağlanır, biri uygulamaya özel, diğeri kullanıcıya özgüdür (tuz gibi). Uygulamaya özel anahtar herhangi bir yerde saklanabilir (web kökünün dışındaki bir yapılandırma dosyasında, çevresel bir değişkende vb.). Kullanıcıya özel şifre şifrelenmiş parolanın yanındaki db sütununda saklanır. Sağlanan kullanıcı depolanmaz. Sonra böyle bir şey yapardın:

    $key = $userKey . $serverKey . $userSuppliedKey;

    Bunun yararı, verilerin hiçbirinden ödün verilmeksizin iki anahtardan herhangi birinin tehlikeye atılmasıdır. Bir SQL Injection saldırısı varsa, bunlar alabilirsiniz $userKey, ancak diğer 2. Bir yerel sunucu istismar varsa, bunlar alabilirsiniz $userKeyve $serverKeyüçü değil $userSuppliedKey. Kullanıcıyı bir anahtarla dövürlerse, $userSuppliedKeydiğer 2'yi alamazlar (ancak daha sonra, kullanıcı bir anahtarla dövülürse, yine de çok geç kalırsınız).

  4. Özel anahtarı saklamak yerine, şifreleri çözülmüş bir şifreye ihtiyaç duyduklarında kullanıcıların özel anahtarı girmelerini istemek iyi bir fikir mi? (Bu uygulamanın kullanıcılarına güvenilebilir)

    Kesinlikle. Aslında, bunu yapmanın tek yolu bu. Aksi takdirde, şifrelenmemiş bir sürümü dayanıklı bir depolama biçiminde (APC veya memcached gibi paylaşılan bellek veya bir oturum dosyasında) saklamanız gerekir. Bu, kendinizi başka tavizlere maruz bırakıyor. Parolanın şifrelenmemiş sürümünü hiçbir zaman yerel değişken dışında bir yerde saklamayın.

  5. Şifre hangi yollarla çalınabilir ve şifresi çözülebilir? Nelerden haberdar olmam gerekir?

    Sistemlerinizin herhangi bir şekilde ele geçirilmesi şifrelenmiş verileri görüntülemelerine izin verir. Kod enjekte edebilir veya dosya sisteminize erişebilirlerse, şifresi çözülmüş verileri görüntüleyebilirler (verilerin şifresini çözen dosyaları düzenleyebildikleri için). Herhangi bir Replay veya MITM saldırısı biçimi de onlara ilgili anahtarlara tam erişim sağlayacaktır. Ham HTTP trafiğini koklamak da onlara anahtarlar verecektir.

    Tüm trafik için SSL kullanın. Sunucudaki hiçbir şeyin herhangi bir güvenlik açığından (CSRF, XSS, SQL Enjeksiyonu, Ayrıcalık Yükselmesi, Uzaktan Kod Yürütme, vb.) Olmadığından emin olun.

Düzenleme: İşte güçlü bir şifreleme yöntemi bir PHP sınıfı uygulaması:

/**
 * A class to handle secure encryption and decryption of arbitrary data
 *
 * Note that this is not just straight encryption.  It also has a few other
 *  features in it to make the encrypted data far more secure.  Note that any
 *  other implementations used to decrypt data will have to do the same exact
 *  operations.  
 *
 * Security Benefits:
 *
 * - Uses Key stretching
 * - Hides the Initialization Vector
 * - Does HMAC verification of source data
 *
 */
class Encryption {

    /**
     * @var string $cipher The mcrypt cipher to use for this instance
     */
    protected $cipher = '';

    /**
     * @var int $mode The mcrypt cipher mode to use
     */
    protected $mode = '';

    /**
     * @var int $rounds The number of rounds to feed into PBKDF2 for key generation
     */
    protected $rounds = 100;

    /**
     * Constructor!
     *
     * @param string $cipher The MCRYPT_* cypher to use for this instance
     * @param int    $mode   The MCRYPT_MODE_* mode to use for this instance
     * @param int    $rounds The number of PBKDF2 rounds to do on the key
     */
    public function __construct($cipher, $mode, $rounds = 100) {
        $this->cipher = $cipher;
        $this->mode = $mode;
        $this->rounds = (int) $rounds;
    }

    /**
     * Decrypt the data with the provided key
     *
     * @param string $data The encrypted datat to decrypt
     * @param string $key  The key to use for decryption
     * 
     * @returns string|false The returned string if decryption is successful
     *                           false if it is not
     */
    public function decrypt($data, $key) {
        $salt = substr($data, 0, 128);
        $enc = substr($data, 128, -64);
        $mac = substr($data, -64);

        list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

        if (!hash_equals(hash_hmac('sha512', $enc, $macKey, true), $mac)) {
             return false;
        }

        $dec = mcrypt_decrypt($this->cipher, $cipherKey, $enc, $this->mode, $iv);

        $data = $this->unpad($dec);

        return $data;
    }

    /**
     * Encrypt the supplied data using the supplied key
     * 
     * @param string $data The data to encrypt
     * @param string $key  The key to encrypt with
     *
     * @returns string The encrypted data
     */
    public function encrypt($data, $key) {
        $salt = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
        list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

        $data = $this->pad($data);

        $enc = mcrypt_encrypt($this->cipher, $cipherKey, $data, $this->mode, $iv);

        $mac = hash_hmac('sha512', $enc, $macKey, true);
        return $salt . $enc . $mac;
    }

    /**
     * Generates a set of keys given a random salt and a master key
     *
     * @param string $salt A random string to change the keys each encryption
     * @param string $key  The supplied key to encrypt with
     *
     * @returns array An array of keys (a cipher key, a mac key, and a IV)
     */
    protected function getKeys($salt, $key) {
        $ivSize = mcrypt_get_iv_size($this->cipher, $this->mode);
        $keySize = mcrypt_get_key_size($this->cipher, $this->mode);
        $length = 2 * $keySize + $ivSize;

        $key = $this->pbkdf2('sha512', $key, $salt, $this->rounds, $length);

        $cipherKey = substr($key, 0, $keySize);
        $macKey = substr($key, $keySize, $keySize);
        $iv = substr($key, 2 * $keySize);
        return array($cipherKey, $macKey, $iv);
    }

    /**
     * Stretch the key using the PBKDF2 algorithm
     *
     * @see http://en.wikipedia.org/wiki/PBKDF2
     *
     * @param string $algo   The algorithm to use
     * @param string $key    The key to stretch
     * @param string $salt   A random salt
     * @param int    $rounds The number of rounds to derive
     * @param int    $length The length of the output key
     *
     * @returns string The derived key.
     */
    protected function pbkdf2($algo, $key, $salt, $rounds, $length) {
        $size   = strlen(hash($algo, '', true));
        $len    = ceil($length / $size);
        $result = '';
        for ($i = 1; $i <= $len; $i++) {
            $tmp = hash_hmac($algo, $salt . pack('N', $i), $key, true);
            $res = $tmp;
            for ($j = 1; $j < $rounds; $j++) {
                 $tmp  = hash_hmac($algo, $tmp, $key, true);
                 $res ^= $tmp;
            }
            $result .= $res;
        }
        return substr($result, 0, $length);
    }

    protected function pad($data) {
        $length = mcrypt_get_block_size($this->cipher, $this->mode);
        $padAmount = $length - strlen($data) % $length;
        if ($padAmount == 0) {
            $padAmount = $length;
        }
        return $data . str_repeat(chr($padAmount), $padAmount);
    }

    protected function unpad($data) {
        $length = mcrypt_get_block_size($this->cipher, $this->mode);
        $last = ord($data[strlen($data) - 1]);
        if ($last > $length) return false;
        if (substr($data, -1 * $last) !== str_repeat(chr($last), $last)) {
            return false;
        }
        return substr($data, 0, -1 * $last);
    }
}

Ben PHP 5.6 eklenen bir işlevi kullanıyorum unutmayın: hash_equals. 5.6'nın altındaysanız, çift ​​HMAC doğrulaması kullanarak zamanlama açısından güvenli bir karşılaştırma işlevi uygulayan bu ikame işlevini kullanabilirsiniz :

function hash_equals($a, $b) {
    $key = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
    return hash_hmac('sha512', $a, $key) === hash_hmac('sha512', $b, $key);
}

Kullanımı:

$e = new Encryption(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
$encryptedData = $e->encrypt($data, $key);

Sonra, şifresini çözmek için:

$e2 = new Encryption(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
$data = $e2->decrypt($encryptedData, $key);

$e2Farklı örneklerin hala verilerin şifresini çözeceğini göstermek için ikinci kez kullandığımı unutmayın .

Şimdi, nasıl çalışıyor / neden başka bir çözüm üzerinde kullanılıyor:

  1. Anahtarlar

    • Tuşlar doğrudan kullanılmaz. Bunun yerine, anahtar standart bir PBKDF2 türevi ile uzatılır.

    • Şifreleme için kullanılan anahtar, şifrelenmiş her metin bloğu için benzersizdir. Dolayısıyla, verilen anahtar bir "ana anahtar" olur. Bu sınıf bu nedenle şifre ve kimlik doğrulama anahtarları için anahtar döndürme sağlar.

    • ÖNEMLİ NOT , $roundsparametre yeterli güce sahip gerçek rastgele anahtarlar için yapılandırılmıştır (en az 128 bit Kriptografik Olarak Güvenli rastgele). Eğer bir şifre veya olmayan rastgele anahtar (CS Random veya daha az rastgele ardından 128 bit) kullanacağız varsa, gereken bu parametreyi arttırır. Şifreler için en az 10000 önerebilirim (ne kadar çok para harcarsanız, o kadar iyi, ancak çalışma zamanına eklenir) ...

  2. Veri bütünlüğü

    • Güncellenmiş sürüm, şifrelenmiş verilerin gerçekliğini sağlamak için çok daha iyi bir yöntem olan ENCRYPT-THEN-MAC kullanır.
  3. Şifreleme:

    • Şifrelemeyi gerçekleştirmek için mcrypt kullanır. Ben ya MCRYPT_BLOWFISHda MCRYPT_RIJNDAEL_128cyphers ve MCRYPT_MODE_CBCmod için kullanmanızı öneririm . Yeterince güçlü ve hala oldukça hızlı (bir şifreleme ve şifre çözme döngüsü makinemde yaklaşık 1/2 saniye sürüyor).

Şimdi, ilk listeden 3. maddeye gelince, bunun size vereceği şey şu şekildedir:

function makeKey($userKey, $serverKey, $userSuppliedKey) {
    $key = hash_hmac('sha512', $userKey, $serverKey);
    $key = hash_hmac('sha512', $key, $userSuppliedKey);
    return $key;
}

İşlevde gerebilirsiniz makeKey(), ancak daha sonra gerileceğinden, bunu yapmanın gerçekten büyük bir anlamı yoktur.

Depolama boyutuna gelince, düz metne bağlıdır. Blowfish 8 baytlık bir blok boyutu kullanır, bu nedenle:

  • Tuz için 16 bayt
  • Hmac için 64 bayt
  • veri uzunluğu
  • Veri uzunluğu% 8 == 0 olacak şekilde doldurma

Yani 16 karakterlik bir veri kaynağı için şifrelenecek 16 karakterlik veri olacaktır. Bu, gerçek şifreli veri boyutunun dolgudan dolayı 16 bayt olduğu anlamına gelir. Daha sonra tuz için 16 bayt ve hmac için 64 bayt ekleyin ve toplam depolanan boyut 96 bayttır. Yani en iyi 80 karakter yükü ve en kötü 87 karakter yükü var ...

Umarım bu yardımcı olur...

Not: 12/11/12: Bu sınıfı daha iyi türetilmiş anahtarlar kullanarak ve MAC üretimini düzelterek çok daha iyi bir şifreleme yöntemiyle güncelledim ...


3
Birisi bunun "kırılma" ne anlama geldiğini anlamıyor. @IRC sınıfta güzel bir iş, bu oldukça lanet olası güzel bir kod.
jcolebrand

1
Aşağıdaki false değerini döndürür. Neden olduğu hakkında bir fikrin var mı? $ x = yeni Şifreleme (MCRYPT_BlOWFISH, MCRYPT_MODE_CBC); $ test = $ x-> şifrelemek ("test", "a"); echo var_dump ($ x-> şifre çözme ($ test, "a"));
Dalga Boyu

2
Oh ve tekrar şifresini çözmek için iki -64s değiştirerek -128yardımcı (böylece olsun $enc = substr($data, 128, -128)ve$mac = substr($data, -128);
cosmorogers

4
@ircmaxell Kodun son revize edilmesinden bu yana oldukça uzun zaman geçti, bu yüzden güncel olup olmadığını merak ediyorum. Ben finansal bir uygulama için benzer bir şey kullanmanız gerekir ve bu sınıf ile iyi bir verdiyseniz güzel olurdu :-)
nt.bas

2
Uyarı! Mcrypt uzantısı neredeyse on yıldır terkedilmiş durumda ve kullanımı oldukça karmaşıktı. Bu nedenle, PHP 7.2'de çekirdekten ve PECL'ye çıkarılacağı OpenSSL lehine kullanımdan kaldırılmıştır. th1.php.net/manual/tr/migration71.deprecated.php
vee

15

PHP'de bir şifreyi nasıl şifreler ve şifresini çözerim? Birçok şifreleme algoritmasından birini uygulayarak. (veya birçok kütüphaneden birini kullanarak)

Şifreleri şifrelemek için en güvenli algoritma nedir? Hiçbiri% 100 güvenli olmayan tonlarca farklı algoritma vardır. Ancak birçoğu ticaret ve hatta askeri amaçlar için yeterince güvenlidir

Özel anahtarı nerede saklayabilirim? Ortak anahtar şifreleme algoritmasını (örneğin RSA) uygulamaya karar verdiyseniz, özel anahtarı depolamazsınız. kullanıcının özel anahtarı var. sisteminizde istediğiniz yerde saklanabilecek bir ortak anahtar bulunur.

Özel anahtarı saklamak yerine, şifreleri çözülmüş bir şifreye ihtiyaç duyduklarında kullanıcıların özel anahtarı girmelerini istemek iyi bir fikir mi? (Bu uygulamanın kullanıcıları güvenilir olabilir) Eğer kullanıcı gülünç uzun asal sayıları hatırlıyorsanız o zaman - evet, neden olmasın. Ancak genellikle kullanıcının anahtarını bir yerde saklamasına izin verecek sistemi bulmanız gerekir.

Şifre hangi yollarla çalınabilir ve şifresi çözülebilir? Nelerden haberdar olmam gerekir? Bu, kullanılan algoritmaya bağlıdır. Ancak, her zaman kullanıcıya şifrelenmemiş bir şifre göndermediğinizden emin olun. İstemci tarafında şifreleyin / şifresini çözün veya https kullanın (veya sunucu ve istemci arasındaki bağlantıyı güvenli hale getirmek için diğer şifreleme araçlarını kullanın).

Ancak parolalarınızı şifrelenmiş bir şekilde saklamak istiyorsanız, basit bir XOR Şifresi kullanmanızı öneririm. Bu algoritma ile ilgili temel sorun frekans analizi ile kolayca kırılabilmesidir. Ancak şifreler genellikle İngilizce metnin uzun paragraflarından yapılmadığından, bunun için endişelenmeniz gerektiğini düşünmüyorum. XOR Cipher ile ilgili ikinci sorun, hem şifreli hem de şifresi çözülmüş biçimde bir mesajınız varsa, şifrelenmiş olduğu şifreyi kolayca bulabilmenizdir. Yine, sadece başka yollarla tehlikeye atılan kullanıcıyı etkilediği için sizin durumunuzda büyük bir sorun değil.


Cevap 3'te, kullanıcıların özel anahtarı olduğunu söylediğinizde bunun ne anlama geldiğini anlamıyorum. Özel anahtarların kullanıcı tarafından uygulamaya manuel olarak geçirilmesini önermezsiniz, bu nedenle özel anahtarlar uygulamaya başka nasıl aktarılır?
HyderA

Bu biraz sorun. Özel anahtar metin dosyasında saklanabilir ve daha sonra uygulamaya yapıştırılmış olarak kopyalanabilir. Anahtar sunucuda da saklanabilir, ancak bu durumda yine de XOR gibi başka bir şifreleme algoritmasıyla şifrelenmelidir. Bu durumda burada XOR kullanımı yeterince güvenlidir çünkü tek bir şifre mesajı çifti vardır ve mesaj oldukça rastgele olduğundan frekans analizi soğuk kullanılmaz.
Ivan

4
Kesinlikle bir şifreleme algoritması uygulamayı tavsiye etmem, çok fazla potansiyel tuzak var ve mevcut kütüphaneler birçok kişi tarafından test edildi ve analiz edildi.
Uzun Kulaklar

XOR ile ilgili temel sorun, birisi uygulama verilerinizi çalarsa ve bir kullanıcının şifrelerinden yalnızca birini biliyorsa, o kullanıcının diğer tüm şifrelerinin şifresini çözebilmesidir.
Uzun Kulaklar

1
@Ivan: evet, ama gerçekten şifrelemeyi anlamadığınız sürece DIY'nin gerçekten kötü olduğunu düşündüğüm durumlardan biri . Var olan güçlü şifreler var, neden onları kullanmıyorsunuz?
ircmaxell

13
  1. Ardarda olduğunuz PHP işlevi Mcrypt ( http://www.php.net/manual/en/intro.mcrypt.php ).

Kılavuzdaki örnek bu örnek için biraz düzenlenmiştir):

<?php
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "This is a very secret key";
$pass = "PasswordHere";
echo strlen($pass) . "\n";

$crypttext = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $pass, MCRYPT_MODE_ECB, $iv);
echo strlen($crypttext) . "\n";
?>

Sen kullanırsınız mcrypt_decrypt şifrenizi şifresini çözmek için.

  1. En iyi algoritma oldukça özneldir - 5 kişiye sorun, 5 cevap alın. Şahsen varsayılan (Blowfish) sizin için yeterince iyi değilse, muhtemelen daha büyük sorunlarınız var!

  2. PHP'nin şifrelemek için gerekli olduğu göz önüne alındığında - herhangi bir yere gizleyebileceğinizden emin değilim - bu konuda hoş geldiniz yorumları. Standart PHP en iyi kodlama uygulamaları elbette geçerlidir!

  3. Şifreleme anahtarının yine de kodunuzda olacağı göz önüne alındığında, uygulamanızın geri kalanının güvenli olması koşuluyla ne kazanacağınızdan emin değilsiniz.

  4. Açıkçası, şifrelenmiş parola ve şifreleme anahtarı çalınırsa, oyun biter.

Cevabımın üzerine bir binici koyardım - PHP kripto uzmanı değilim, ama cevapladığım şeyin standart uygulama olduğunu düşünüyorum - diğerlerinin sahip olabileceği yorumları hoş geldiniz.


$pass = $text. Bence soruyu karşılamak için değiştirdi ve ikinci olayı fark etmedi.
HyderA

3
Dikkat edilmesi gereken iki şey. İlk olarak MCRYPT_MODE_ECBIV kullanmayın. İkincisi, eğer öyleyse, IV'ü onsuz şifresini
çözemediğiniz için saklamanız

"En iyi algoritma oldukça özneldir - 5 kişiye sorun, 5 cevap alın. Varsayılan olarak (Blowfish) sizin için yeterince iyi değilse, muhtemelen daha büyük sorunlarınız var!" Bu tamamen yanlış. Herhangi kripto uzmanı olacak daha fazla veya daha az katılıyorum gist.github.com/tqbf/be58d2d39690c3b366ad özellikle dışlayan Blowfish hangi
Scott Arciszewski

6

Birçok kullanıcı mcrypt kullanmayı önerdi ... bu doğru, ancak kolayca saklanıp aktarılması için bir adım daha ileri gitmeyi seviyorum (bazen şifrelenmiş değerler curl veya json gibi diğer teknolojileri kullanarak gönderilmesini zorlaştırabilir) .

Mcrypt kullanarak başarılı bir şekilde şifreledikten sonra, base64_encode ile çalıştırın ve onaltılı koda dönüştürün. Onaltılık kod bir kez çeşitli şekillerde aktarmak kolaydır.

$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$key = substr("SUPERSECRETKEY",0,mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$encrypted = mcrypt_generic($td, $unencrypted);
$encrypted = $ua."||||".$iv;
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$encrypted = base64_encode($encrypted);
$encrypted = array_shift(unpack('H*', $encrypted));

Ve diğer tarafta:

$encrypted = pack('H*', $encrypted);
$encrypted = base64_decode($encrypted);
list($encrypted,$iv) = explode("||||",$encrypted,2);
$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$key = substr("SUPERSECRETKEY",0,mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$unencrypted = mdecrypt_generic($td, $encrypted);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);


2
Peki - 2011
Bradley

5

Genel anahtar şifrelemesini yalnızca etkileşimi olmadan bir kullanıcının şifresini ayarlayabiliyorsanız öneririm (bu, sıfırlamalar ve paylaşılan şifreler için kullanışlı olabilir).

Genel anahtar

  1. OpenSSL uzantısı, özel olarak openssl_public_encryptveopenssl_private_decrypt
  2. Parolalarınızın anahtar boyutuna sığacağını varsayarak düz RSA olurdu - dolgu, aksi takdirde simetrik bir katmana ihtiyacınız vardır
  3. Her kullanıcı için her iki anahtarı da saklayın, özel anahtarın parolası uygulama şifresidir

Simetrik

  1. Mcrypt uzantısı
  2. AES-256 muhtemelen güvenli bir bahistir, ancak bu kendi içinde bir SO sorusu olabilir
  3. Yapmazsınız - bu onların uygulama şifresi olurdu

Her ikisi de

4. Evet - kullanıcıların uygulama şifrelerini her seferinde girmeleri gerekir, ancak oturumda saklanması başka sorunları da beraberinde getirir

5.

  • Birisi uygulama verilerini çalarsa, simetrik şifre kadar güvenlidir (ortak anahtar şeması için, özel anahtarı parola ile korumak için kullanılır.)
  • Uygulamanıza yalnızca SSL üzerinden, tercihen istemci sertifikaları kullanılarak erişilebilir olmalıdır.
  • SMS yoluyla gönderilen bir belirteç gibi, oturum başına yalnızca bir kez kullanılacak kimlik doğrulama için ikinci bir faktör eklemeyi düşünün.

Mcrypt kaçının, dikkatli olun openssl_private_decrypt().
Scott Arciszewski

2

Böyle bir şey denedim ama kriptograf olmadığımı phpveya herhangi bir programlama dili hakkında derinlemesine bilgi sahibi olmadığımı lütfen unutmayın . Bu sadece bir fikir. Benim fikrim bir keydosyada saklamak veya database(veya manuel olarak girmek) hangi (konum) kolayca tahmin edilemez (Ve tabii ki her şey şifresi çözülecek, konsept şifre çözme süresini uzatmak) ve hassas bilgileri şifrelemek.

$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH , MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "evenifyouaccessmydatabaseyouwillneverfindmyemail";
$text = "myemail@domain.com";
echo "Key : ".$key."<br/>";
echo "Text : ".$text . "<br/>";
echo "Md5 : ".md5($text). "<br/>";
echo "Sha1 : ".sha1($text). "<br/>";



$crypttext = mcrypt_encrypt(MCRYPT_BLOWFISH , $key, $text, MCRYPT_MODE_ECB, $iv);
echo "Crypted Data : ".$crypttext."<br>";

$base64 = base64_encode($crypttext);
echo "Encoded Data : ".$base64."<br/>";
$decode =  base64_decode($base64);


$decryptdata = mcrypt_decrypt(MCRYPT_BLOWFISH , $key, $crypttext, MCRYPT_MODE_ECB, $iv);

echo "Decoded Data : ".ereg_replace("?", null ,  $decryptdata); 
//event if i add '?' to the sting to the text it works, I don't know why.

Lütfen bunun sadece bir kavram olduğunu unutmayın. Bu koddaki herhangi bir gelişme çok takdir edilecektir.


2

Parolalar bir donanım aygıtı içindir, bu nedenle karmaları kontrol etmek söz konusu değildir

Eh? Anlamıyorum. Sadece şifrenin kurtarılabilir olması gerektiği anlamına mı geliyor?

Diğerlerinin söylediği gibi, mcrypt uzantısı birçok şifreleme işlevine erişim sağlar - ancak kullanıcılarınızı tüm yumurtalarını tek bir sepete koymaya davet edersiniz - biri saldırganların hedefi olacak - ve hatta bilmiyorsanız nasıl sorunu çözmeye başlamak için kullanıcılarınızı bir kötülük yapıyoruz. Verilerin nasıl korunacağını anlayacak durumda değilsiniz.

Çoğu güvenlik açıkları, altta yatan algoritmanın kusurlu veya güvensiz olması nedeniyle değil, algoritmanın uygulama kodunda kullanılma şeklindeki sorunlardan kaynaklanmaktadır.

Bunu söyledikten sonra, oldukça güvenli bir sistem kurmak mümkündür .

Asimetrik şifrelemeyi, yalnızca bir kullanıcının başka (belirli) bir kullanıcı tarafından okunabilen güvenli bir ileti oluşturma gereksiniminiz varsa dikkate almalısınız. Bunun nedeni, hesaplama açısından pahalı olmasıdır. Kullanıcıların yalnızca kendi verilerini girip almaları için bir havuz sağlamak istiyorsanız, simetrik şifreleme yeterlidir.

Ancak, mesajın şifresini çözmek için anahtarı şifreli mesajla aynı yerde (veya şifreli mesajın saklandığı yerde) saklarsanız, sistem güvenli değildir. Şifre çözme anahtarı için kullanıcının kimliğini doğrulamak için aynı jetonu kullanın (veya asimetrik şifreleme durumunda jetonu özel anahtar geçiş deyimi olarak kullanın). Şifreyi en azından geçici olarak çözme işleminin yapıldığı sunucuda depolamanız gerekeceğinden, aranamayan bir oturum depolama alt katmanı kullanmayı veya jetonu doğrudan bellekte token ve istek üzerine mesajların şifresini çözmek.


1

Password_hash ve password_verify kullanın

<?php
/**
 * In this case, we want to increase the default cost for BCRYPT to 12.
 * Note that we also switched to BCRYPT, which will always be 60 characters.
 */
$options = [
    'cost' => 12,
];
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
?>

Ve şifresini çözmek için:

<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';

if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
?>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.