أفضل طريقة لاستخدام PHP لتشفير وفك تشفير كلمات المرور؟ [مكرر

StackOverflow https://stackoverflow.com/questions/1289061

سؤال

ممكن مكررة:
PHP 2-Way Encryption: أحتاج إلى تخزين كلمات المرور التي يمكن استرجاعها

أخطط لتخزين معلومات الحساب الأجنبية لمستخدمي على موقع الويب الخاص بي على موقع الويب الخاص بي و AKA Rapidshare اسم المستخدم وكلمات المرور وما إلى ذلك ... أريد الاحتفاظ بالمعلومات آمنة، لكنني أعرف أنه إذا قمت بمعلوماتهم، لا يمكنني استرجاعها لاستخدامها لاحقا وبعد

BASS64 هو فك تشفير القدرة حتى لا يكون هناك نقطة باستخدام هذا مجرد إيقاف. فكرتي هي أن تدافع المستخدم وتمرير قبل وبعد أن تحصل على Base64ed بهذه الطريقة حتى بعد فك تشفيرها، تحصل على بعض النص المظهر مضحك إذا حاولت فك تشفيرها. هل هناك وظيفة PHP التي تقبل القيم التي من شأنها أن تجعل فريدة من نوعها سلسلة من سلسلة وإزالة التدافع في وقت لاحق عند إعادة تسجيل القيمة؟

أي اقتراحات؟

هل كانت مفيدة؟

المحلول

يجب عدم تشفير كلمات المرور، بدلا من ذلك، يجب عليك التكلفة باستخدام خوارزمية مثل Bcrypt. يشرح هذا الجواب كيفية تطبيق كلمة المرور بشكل صحيح في PHP. لا يزال، هنا كيف يمكنك تشفير / فك تشفير:

$key = 'password to (en/de)crypt';
$string = ' string to be encrypted '; // note the spaces

لتشفير:

$iv = mcrypt_create_iv(
    mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC),
    MCRYPT_DEV_URANDOM
);

$encrypted = base64_encode(
    $iv .
    mcrypt_encrypt(
        MCRYPT_RIJNDAEL_128,
        hash('sha256', $key, true),
        $string,
        MCRYPT_MODE_CBC,
        $iv
    )
);

فك تشفير:

$data = base64_decode($encrypted);
$iv = substr($data, 0, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));

$decrypted = rtrim(
    mcrypt_decrypt(
        MCRYPT_RIJNDAEL_128,
        hash('sha256', $key, true),
        substr($data, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)),
        MCRYPT_MODE_CBC,
        $iv
    ),
    "\0"
);

تحذير: المثال أعلاه تشفير المعلومات، لكنها لا مصادقة النص المشفر لمنع العبث. يجب ليس الاعتماد على تشفير غير مصادق للأمن, ، خاصة وأن الكود كما هو موضح هو عرضة للحشو هجمات أوراكل.

أنظر أيضا:

أيضا، لا تستخدم فقط "كلمة مرور" لمفتاح التشفير. مفاتيح التشفير هي سلاسل عشوائية.


تجريبي في 3V4L.org.:

echo 'Encrypted:' . "\n";
var_dump($encrypted); // "m1DSXVlAKJnLm7k3WrVd51omGL/05JJrPluBonO9W+9ohkNuw8rWdJW6NeLNc688="

echo "\n";

echo 'Decrypted:' . "\n";
var_dump($decrypted); // " string to be encrypted "

نصائح أخرى

تحذير الأمان: هذه الفئة ليست آمنة. انها تستخدم Rijndael256-ECB., ، والتي ليست آمنة دلالة. فقط لأن "الأمر يعمل" لا يعني "إنه آمن". أيضا، يشرف مساحات الذخيرة بعد ذلك بسبب عدم استخدام الحشو السليم.

وجدت هذه الفئة مؤخرا، وهي تعمل مثل الحلم!

class Encryption {
    var $skey = "yourSecretKey"; // you can change it

    public  function safe_b64encode($string) {
        $data = base64_encode($string);
        $data = str_replace(array('+','/','='),array('-','_',''),$data);
        return $data;
    }

    public function safe_b64decode($string) {
        $data = str_replace(array('-','_'),array('+','/'),$string);
        $mod4 = strlen($data) % 4;
        if ($mod4) {
            $data .= substr('====', $mod4);
        }
        return base64_decode($data);
    }

    public  function encode($value){ 
        if(!$value){return false;}
        $text = $value;
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->skey, $text, MCRYPT_MODE_ECB, $iv);
        return trim($this->safe_b64encode($crypttext)); 
    }

    public function decode($value){
        if(!$value){return false;}
        $crypttext = $this->safe_b64decode($value); 
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->skey, $crypttext, MCRYPT_MODE_ECB, $iv);
        return trim($decrypttext);
    }
}

وندعوها:

$str = "My secret String";

$converter = new Encryption;
$encoded = $converter->encode($str );
$decoded = $converter->decode($encoded);    

echo "$encoded<p>$decoded";

تحذير الأمان: هذا الرمز غير آمن.

مثال على ذلك

define('SALT', 'whateveryouwant'); 

function encrypt($text) 
{ 
    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SALT, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)))); 
} 

function decrypt($text) 
{ 
    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, SALT, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))); 
} 

$encryptedmessage = encrypt("your message"); 
echo decrypt($encryptedmessage); 

شيء واحد يجب أن تكون على دراية للغاية عند التعامل مع التشفير:

تحاول أن تكون ذكيا واختراع الشيء الخاص بك عادة سيغادرك شيئا غير آمن.

من المحتمل أن تكون أفضل قبالة باستخدام واحدة من ملحقات التشفير التي تأتي مع php.

هذا سوف يمنحك فقط الحماية الهامشية. إذا كان المهاجم يمكنه تشغيل رمز تعسفي في طلبك، فيمكنهم الحصول على كلمات المرور بنفس الطريقة بالطريقة نفسها التي يمكن تطبيقها. لا يزال بإمكانك الحصول على بعض الحماية من بعض الهجمات حقن SQL ونسخ احتياطية DB في غير محله إذا قمت بتخزين مفتاح سري في ملف واستخدام ذلك للتشفير في الطريق إلى DB وفك تشفير في الطريق. ولكن يجب عليك استخدام BindParams لتجنب إذن حقن SQL بالكامل.

إذا قرر التشفير، يجب عليك استخدام بعض مكتبة التشفير عالية المستوى لهذا، أو أنت إرادة أسأت الفهم. سيكون عليك الحصول على إعداد المفاتيح، وحشو الرسائل وفحص النزاهة الصحيحة، أو كل جهد التشفير الخاص بك من الاستخدام القليل. GPGME. هو اختيار جيد مثال واحد. Mcrypt مستوى منخفض للغاية وسوف تحصل عليه من الخطأ.

تحذير Securiy: هذا الرمز هو غير آمن. وبعد بالإضافة إلى كونها عرضة للهجمات المختارة والترفيهة، اعتمادها unserialize() يجعلها عرضة لحقن كائن PHP.

للتعامل مع سلسلة / صفيف يمكنني استخدام هاتين الوظيفتين:

function encryptStringArray ($stringArray, $key = "Your secret salt thingie") {
 $s = strtr(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), serialize($stringArray), MCRYPT_MODE_CBC, md5(md5($key)))), '+/=', '-_,');
 return $s;
}

function decryptStringArray ($stringArray, $key = "Your secret salt thingie") {
 $s = unserialize(rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode(strtr($stringArray, '-_,', '+/=')), MCRYPT_MODE_CBC, md5(md5($key))), "\0"));
 return $s;
}

إنه مرن كما يمكنك تخزين / إرسال عبر عنوان URL سلسلة أو صفيف لأن السلسلة / الصفيف هو Serialzed قبل التشفير.

تحقق من mycrypt (): http://us.php.net/manual/en/book.mcrypt.php.

وإذا كنت تستخدم Postgres، فهناك pgcrypto لتشفير مستوى قاعدة البيانات. (يجعل من السهل البحث والفرز)

أفضل فكرة تشفير / فك تشفير البيانات الخاصة بك في قاعدة البيانات حتى لو كان لديك حق الوصول إلى الرمز هو استخدام 2 مختلف يمر كلمة مرور خاصة (user-pass) لكل مستخدم ورمز خاص لجميع المستخدمين (system-pass).

سيناريو

  1. user-pass يتم تخزينها مع MD5 في قاعدة البيانات ويتم استخدامها للتحقق من صحة كل مستخدم لتسجيل الدخول إلى النظام. هذا تمرير المستخدم هو مختلف لكل مستخدم.
  2. كل إدخال مستخدم في قاعدة البيانات لديه في MD5 system-pass لتشفير / فك التشفير من البيانات. هذا النظام المرور هو نفس لكل مستخدم.
  3. في أي وقت يتم إزال المستخدم من النظام، يجب تشفير جميع البيانات التي يتم تشفيرها تحت تمرير النظام القديم مرة أخرى تحت تمرير نظام جديد لتجنب مشكلات الأمان.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top