SORU
6 HAZİRAN 2012, ÇARŞAMBA


Nasıl php/şifresini şifrelemek için?

Şu anda öğrenciyim ve PHP, PHP veri basit şifrelemek/şifresini çözmek için çalışıyorum okuyorum. Bazı çevrimiçi araştırma yaptım ve bazıları oldukça kafa karıştırıcı(en azından benim için).

Yapmaya çalıştığım şey şu:

Bir tablo bu alanlarda oluşan() Kullanıcı Kimliği,Fname,Lname,E-Posta,Şifre

Sahip olmak istediğim tüm alanları şifreli ve şifresi mümkün şifreleme/sha256 kullanmak için şifre çözme, eğer herhangi bir şifreleme algoritması () sonra

Öğrenmek istediğim başka birşey daha 11* *tek bir yolu iyi bir kombine oluşturmak için nasıl"". tuz (Aslında ben sadece şifreleme/basit bir uygulama, 12 **şifre çözme sahip olmak istiyorum Efendim, efendim/Ma cevaplar çok yardımcı olacak ve çok mutluluk duyacağız. Teşekkür ederim

CEVAP
8 HAZİRAN 2012, Cuma


Önsöz

Tablo tanımı ile başlıyor:

- UserID
- Fname
- Lname
- Email
- Password
- IV

İşte değişiklikler:

  1. Fname, Lname Email şifrelenir alanları simetrik şifreleme kullanarak OpenSSL tarafından sağlanan
  2. IV alan initialisation vector şifreleme için kullanılan depolar. Depolama gereksinimleri ve şifre modu kullanılır; bu konuda daha sonra değişir.
  3. Password alan karma bir kullanımı olacaktek yönlüparola hash

Şifreleme

Şifre ve mod

Seçme en iyi şifreleme ve mod ötesinde kapsamında bu cevap, ama son seçim etkiler boyutta hem şifreleme anahtar ve başlatma vektörü; bu yazı olacağız kullanarak AES-256-CBC olan bir sabit blok boyutu 16 bayt ve anahtar boyutu da 16, 24 veya 32 bayt.

Şifreleme anahtarı

İyi bir şifreleme anahtarı güvenilir bir rasgele sayı üreteci tarafından oluşturulan bu ikili bir blob. Aşağıdaki örnek tavsiye (>= 5.3):

$key_size = 32; // 256 bits
$encryption_key = openssl_random_pseudo_bytes($key_size, $strong);
// $strong will be true if the key is crypto safe

Bu işlem tamamlandıktan sonra ya da birden çok kez, şifreleme anahtarları zinciri oluşturmak istiyorsanız () olabilir. Bu mümkün olduğunca gizli tutun.

IV

Başlatma vektörü şifreleme rastgelelik ekler ve CBC modu için gerekli. Bu değerler bir satır, herhangi bir güncelleştirme bunu yeniden gerekir bu yüzden en iyisi sadece bir kez (şifreleme anahtarı başına teknik olarak bir kez) kullanılması gerekir.

Bir fonksiyon IV oluşturmak yardımcı olmak için sağlanmıştır:

$iv_size = 16; // 128 bits
$iv = openssl_random_pseudo_bytes($iv_size, $strong);

Örnek

Hadi adını alan, daha önce $encryption_key kullanarak şifrelemek ve $iv; bunu yapmak için, blok boyutu için veri yazma var:

function pkcs7_pad($data, $size)
{
    $length = $size - strlen($data) % $size;
    return $data . str_repeat(chr($length), $length);
}

$name = 'Jack';
$enc_name = openssl_encrypt(
    pkcs7_pad($name, 16), // padded data
    'AES-256-CBC',        // cipher and mode
    $encryption_key,      // secret key
    0,                    // options (not used)
    $iv                   // initialisation vector
);

Depolama gereksinimleri

Şifreli çıktı, IV, ikili; bir veritabanında bu değerleri saklamak BINARY VARBINARY gibi belirlenen sütun türleri kullanılarak gerçekleştirilebilir.

Çıkış değeri, IV, ikili; MySQL bu değerleri saklamak için, BINARY or VARBINARY sütun kullanmayı düşünün. Eğer bu bir seçenek değil, aynı zamanda metinsel gösterimi base64_encode() veya bin2hex(), 33 0% arasında daha fazla depolama alanı gerektirir böylece kullanarak ikili veri dönüştürebilirsiniz.

Şifre çözme

Saklı değerler çözme benzer:

function pkcs7_unpad($data)
{
    return substr($data, 0, -ord($data[strlen($data) - 1]));
}

$row = $result->fetch(PDO::FETCH_ASSOC); // read from database result
// $enc_name = base64_decode($row['Name']);
// $enc_name = hex2bin($row['Name']);
$enc_name = $row['Name'];
// $iv = base64_decode($row['IV']);
// $iv = hex2bin($row['IV']);
$iv = $row['IV'];

$name = pkcs7_unpad(openssl_decrypt(
    $enc_name,
    'AES-256-CBC',
    $encryption_key,
    0,
    $iv
));

Şifreleme kimliği doğrulanmış

Daha fazla gizli anahtarı (şifreleme anahtarı farklı) ve şifre metni oluşturulan bir imza ekleyerek oluşturulan şifre metni bütünlüğü artırabilir. Şifre metin şifresi önce, ilk imza (tercihen sabit zaman karşılaştırma yöntemi ile) doğrulanmıştır.

Örnek

// generate once, keep safe
$auth_key = openssl_random_pseudo_bytes(32, $strong);

// authentication
$auth = hash_hmac('sha256', $enc_name, $auth_key, true);
$auth_enc_name = $auth . $enc_name;

// verification
$auth = substr($auth_enc_name, 0, 32);
$enc_name = substr($auth_enc_name, 32);
$actual_auth = hash_hmac('sha256', $enc_name, $auth_key, true);

if (hash_equals($auth, $actual_auth)) {
    // perform decryption
}

Ayrıca bakınız: hash_equals()

Karma

Veritabanınızda tersinir bir parola saklamak mümkün olduğunca kaçınılmalıdır; sadece parolayı doğrulamak için içeriğini bilmek yerine keşke. Eğer bir kullanıcı kendi şifresini kaybederse, onlara orijinal bir (parola sıfırlama sadece yapılabilir emin sınırlı bir süre için) göndermek yerine bunu sıfırlamak için izin vermek için.

Uygulamadan bir hash fonksiyonu tek yönlü bir işlem; daha sonra olabilir güvenle kullanılan bir doğrulama olmadan açığa orijinal veri, şifre, bir kaba kuvvet yöntemi uygulanabilir bir yaklaşım ortaya çıkarma nedeniyle nispeten kısa boy ve zayıf şifre seçimler pek çok kişi.

MD5 veya SHA1 gibi karma algoritmalar bilinen hash değeri karşı dosya içeriğini doğrulamak için yapıldı. Büyük ölçüde hala doğru olurken bu doğrulama mümkün olduğunca hızlı yapmak için optimize ediyorlar. Kolay bilinen şifreleri ve ilgili karma çıkışları, gökkuşağı tablo ile bir veritabanı oluşturmak için alanı nispeten sınırlı çıkış verildi.

Bu karma önce şifre için bir tuz ekleyerek bir gökkuşağı tablo yaramaz hale getirecektir, ancak son gelişmeler donanım kaba kuvvet aramalar uygulanabilir bir yaklaşım yaptı. Kasten yavaş ve optimize etmek için sadece imkansız bir karma algoritma ihtiyacımız var. Ayrıca mevcut şifre sağlamalarının, gelecek geçirmez yapmak için doğrulamak için yeteneğini etkilemeden daha hızlı donanım yükünü artırmak gerekir.

Şu anda iki popüler seçenek vardır:

  1. PBKDF2 (Parola Tabanlı Anahtar elde edilmesini İşlevi v2)
  2. bcrypt (nam-ı diğer kirpi Balığı)

Bu cevap bcrypt ile bir örnek olacaktır.

Nesil

Parola karma bu gibi oluşturulabilir:

$password = 'my password';
$random = openssl_random_pseudo_bytes(18);
$salt = sprintf('$2y$d$%s',
    13, // 2^n cost factor
    substr(strtr(base64_encode($random), ' ', '.'), 0, 22)
);

$hash = crypt($password, $salt);

Tuz openssl_random_pseudo_bytes() base64_encode() strtr() [A-Za-z0-9/.] gerekli alfabesi maç için çalışacak olan veri rasgele bir damla şeklinde oluşturulur.

crypt() fonksiyona karma tabanlı algoritma ($2y$ Blowfish), maliyet faktörü (faktör 13 alır yaklaşık 0.40 s 3 GHz bir makine) ve tuz 22 karakter.

Doğrulama

Satır kullanıcı bilgilerini içeren bir ihtimal var, bu şekilde şifreyi doğrula:

$given_password = $_POST['password']; // the submitted password
$db_hash = $row['Password']; // field with the password hash

$given_hash = crypt($given_password, $db_hash);

if (isEqual($given_hash, $db_hash)) {
    // user password verified
}

// constant time string compare
function isEqual($str1, $str2)
{
    $n1 = strlen($str1);
    if (strlen($str2) != $n1) {
        return false;
    }
    for ($i = 0, $diff = 0; $i != $n1;   $i) {
        $diff |= ord($str1[$i]) ^ ord($str2[$i]);
    }
    return !$diff;
}

Bir şifre doğrulamak için crypt() tekrar arayın ama salt değeri olarak daha önce hesaplanan hash geçirir. Dönüş değeri eğer verilen parola karma eşleşirse aynı hash üretir. Karma doğrulamak için, genellikle sabit zamanlı bir karşılaştırma işlevi zamanlama saldırıları önlemek için kullanılması tavsiye edilir.

Parola PHP ile karma 5.5

PHP 5.5 karma yukarıdaki yöntemi kolaylaştırmak için kullanabileceğiniz password hashing functions tanıttı:

$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 13]);

Ve doğrulama:

if (password_verify($given_password, $db_hash)) {
    // password valid
}

Ayrıca Bkz: password_hash(), password_verify()

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • chickenby

    chickenby

    2 HAZİRAN 2008
  • 10 Daughters, 2 Sons

    10 Daughters

    10 Mart 2009
  • JonnyEthco

    JonnyEthco

    5 EKİM 2006