পিএইচপি ব্যবহার করে সবচেয়ে সহজ দ্বিমুখী এনক্রিপশন


230

সাধারণ পিএইচপি ইনস্টলগুলিতে দ্বিমুখী এনক্রিপশন করার সহজ উপায় কী?

আমার স্ট্রিং কী দিয়ে ডেটা এনক্রিপ্ট করতে সক্ষম হতে হবে এবং অন্য প্রান্তে ডিক্রিপ্ট করার জন্য একই কীটি ব্যবহার করতে হবে।

সুরক্ষা কোডের বহনযোগ্যতার মতো উদ্বেগের মতো বড় নয়, তাই আমি যতটা সম্ভব জিনিসগুলিকে সহজ করে রাখতে সক্ষম হতে চাই। বর্তমানে, আমি একটি আরসি 4 বাস্তবায়ন ব্যবহার করছি, তবে যদি আমি স্থানীয়ভাবে সমর্থিত কোনও কিছু খুঁজে পাই তবে আমি বুঝতে পারি যে অনেকগুলি অপ্রয়োজনীয় কোড সংরক্ষণ করতে পারি।



3
সাধারণ উদ্দেশ্যে এনক্রিপশনের জন্য, নিজের রোলিংয়ের পরিবর্তে ডিফিউজ / পিএইচপি-এনক্রিপশন / ব্যবহার করুন।
স্কট আর্কিসজেউস্কি

2
Github.com/defuse/php- এনক্রিপশন থেকে হাত দূরে - এটি এমক্রিপ্টের চেয়ে প্রস্থের আদেশ দ্বারা ধীর।
ইউজেন রিইক

1
@ স্কট "এটি সম্ভবত বাধা হয়ে দাঁড়াবে না" "র লাইন ধরে ভাবনা আমাদের অনেক খারাপ সফ্টওয়্যার নিয়ে এসেছিল।
ইউজেন রিইক

3
আপনি যদি সত্যিই প্রচুর ডেটা এনক্রিপ্ট / ডিক্রিপ্ট করে থাকেন যে মিলি সেকেন্ডের জন্য এটি প্রয়োগ করে আপনার অ্যাপ্লিকেশনটি নিচে নেমে আসে, বুলেটটি কামড়ান এবং লাইবসোডিয়ামে স্যুইচ করুন। Sodium::crypto_secretbox()এবং Sodium::crypto_secretbox_open()সুরক্ষিত এবং পারফরম্যান্ট।
স্কট আর্কিসজেউস্কি 12:58

উত্তর:


196

সম্পাদিত:

আপনি সত্যিই ওপেনএসএল_ইনক্রিপ্ট () এবং ওপেনসেল_ডেক্রিপ্ট () ব্যবহার করা উচিত

স্কট যেমন বলেছিলেন, ম্যাক্রিপ্ট ভাল ধারণা নয় কারণ এটি 2007 সাল থেকে আপডেট হয়নি।

এমনকি পিএইচপি থেকে ম্যাক্রিপ্ট সরানোর জন্য একটি আরএফসি রয়েছে - https://wiki.php.net/rfc/mcrypt-viking-funeral


6
@ ইউজেনরাইক হ্যাঁ, এটিই মূল বিষয়। ম্যাক্রিপ্ট প্যাচগুলি পান না। বড় বা ছোট কোনও দুর্বলতা আবিষ্কার হওয়ার সাথে সাথে ওপেনএসএসএল প্যাচগুলি গ্রহণ করে।
গ্রেগ

5
এই জাতীয় উচ্চ-ভোটযুক্ত উত্তরের জন্য উত্তম হবে, সেখানে উত্তরের মধ্যে সাদামাটা উদাহরণ প্রদান করা উচিত। যাই হোক ধন্যবাদ.
টুডো

ছেলেরা, কেবল FYI => এমসিআরওয়াইপিটি অগ্রাহ্য। ক্যাপসিং করা যাতে এটি ব্যবহার না করা প্রত্যেকেরই জানা উচিত কারণ এটি আমাদেরকে একটি অগণিত সমস্যা দিয়েছে। যদি আমি ভুল না হয়ে থাকি তবে এটি পিএইচপি 7.1 এর পরে অবনতি হয়েছে।
ক্লাস্টারবাডি

যেহেতু পিএইচপি 7 এমক্রিপ্ট ফাংশন পিএইচপি কোডবেস থেকে সরানো হয়েছে। সুতরাং পিএইচপি (যা স্ট্যান্ডার্ড হওয়া উচিত) এর সর্বশেষতম সংস্করণ ব্যবহার করার সময় আপনি এই অবহেলা ফাংশনটি আর ব্যবহার করতে পারবেন না।
আলেকজান্ডার বেহলিং

234

গুরুত্বপূর্ণ : আপনার যদি খুব নির্দিষ্ট ব্যবহারের ক্ষেত্রে না থাকে তবে পাসওয়ার্ডগুলি এনক্রিপ্ট করবেন না , পরিবর্তে পাসওয়ার্ড হ্যাশিং অ্যালগরিদম ব্যবহার করুন। যখন কেউ বলে যে তারা সার্ভার-সাইড অ্যাপ্লিকেশনটিতে তাদের পাসওয়ার্ডগুলি এনক্রিপ্ট করেছে, তারা হয় অজানা বা তারা একটি বিপজ্জনক সিস্টেমের নকশা বর্ণনা করছে। পাসওয়ার্ডগুলি নিরাপদে সংরক্ষণ করা এনক্রিপশন থেকে সম্পূর্ণ পৃথক সমস্যা।

অবহিত হতে হবে। নিরাপদ সিস্টেম ডিজাইন।

পিএইচপি-তে পোর্টেবল ডেটা এনক্রিপশন

আপনি যদি পিএইচপি 5.4 বা তার থেকেও বেশি ব্যবহার করে থাকেন এবং নিজে কোনও ক্রিপ্টোগ্রাফি মডিউল লিখতে না চান তবে আমি একটি বিদ্যমান লাইব্রেরি ব্যবহার করার পরামর্শ দিচ্ছি যা প্রমাণীকৃত এনক্রিপশন সরবরাহ করে । আমি যে লাইব্রেরিটি সংযুক্ত করেছি তা কেবলমাত্র পিএইচপি সরবরাহ করে এবং তার উপর নির্ভর করে মুষ্টিমেয় নিরাপত্তা গবেষকরা ic (নিজেকে অন্তর্ভুক্ত।)

আপনার বহনযোগ্যতা গোল PECL এক্সটেনশন প্রয়োজন প্রতিরোধ না থাকে, তাহলে libsodium হয় অত্যন্ত কিছুর উপর সুপারিশ আপনি বা আমি পিএইচপি লিখতে পারেন।

আপডেট (২০১-0-০6-১২): আপনি এখন সোডিয়াম_কম্প্যাট ব্যবহার করতে পারেন এবং পিইসিএল এক্সটেনশানগুলি ইনস্টল না করে একই ক্রিপ্টো লাইবসোডিয়াম অফারগুলি ব্যবহার করতে পারেন।

আপনি যদি ক্রিপ্টোগ্রাফি ইঞ্জিনিয়ারিংয়ে হাত চেষ্টা করতে চান তবে পড়ুন।


প্রথমত, অচিহ্নযুক্ত এনক্রিপশন এবং ক্রিপ্টোগ্রাফিক ডুম নীতিমালার বিপদগুলি শিখতে আপনার সময় নেওয়া উচিত ।

  • এনক্রিপ্ট করা ডেটা এখনও দূষিত ব্যবহারকারীর দ্বারা টেম্পার করতে পারে।
  • এনক্রিপ্ট করা ডেটা প্রমাণীকরণ হস্তক্ষেপে বাধা দেয়।
  • এনক্রিপ্ট করা ডেটা প্রমাণীকরণ, হস্তক্ষেপ রোধ করে না।

এনক্রিপশন এবং ডিক্রিপশন

পিএইচপি-তে এনক্রিপশন আসলে সহজ (আমরা ব্যবহার করতে যাচ্ছি openssl_encrypt()এবং openssl_decrypt()একবার আপনি কীভাবে আপনার তথ্য এনক্রিপ্ট করবেন সে সম্পর্কে কিছু সিদ্ধান্ত নিয়েছেন your openssl_get_cipher_methods()আপনার সিস্টেমে সমর্থিত পদ্ধতির তালিকার জন্য পরামর্শ নিন C সিটিআর মোডে সেরা পছন্দটি হচ্ছে এইএস :

  • aes-128-ctr
  • aes-192-ctr
  • aes-256-ctr

বর্তমানে এটির কোনও কারণ নেই যে এইএস কী আকারটি উদ্বিগ্ন হওয়ার জন্য একটি তাত্পর্যপূর্ণ সমস্যা ( 256-বিট মোডে খারাপ কী-শিডিয়ুলিংয়ের কারণে বড় সম্ভবত সম্ভবত এটি ভাল নয় )।

দ্রষ্টব্য: আমরা mcryptএটি ব্যবহার করছি না কারণ এটি পরিত্যক্ত ওয়ার্ল্ড এবং আনপ্যাচড বাগ রয়েছে যা সুরক্ষা-প্রভাবিত করতে পারে। এই কারণগুলির কারণে, আমি অন্যান্য পিএইচপি বিকাশকারীদের এটি এড়াতেও উত্সাহিত করি।

ওপেনএসএসএল ব্যবহার করে সাধারণ এনক্রিপশন / ডিক্রিপশন র‍্যাপার

class UnsafeCrypto
{
    const METHOD = 'aes-256-ctr';

    /**
     * Encrypts (but does not authenticate) a message
     * 
     * @param string $message - plaintext message
     * @param string $key - encryption key (raw binary expected)
     * @param boolean $encode - set to TRUE to return a base64-encoded 
     * @return string (raw binary)
     */
    public static function encrypt($message, $key, $encode = false)
    {
        $nonceSize = openssl_cipher_iv_length(self::METHOD);
        $nonce = openssl_random_pseudo_bytes($nonceSize);

        $ciphertext = openssl_encrypt(
            $message,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $nonce
        );

        // Now let's pack the IV and the ciphertext together
        // Naively, we can just concatenate
        if ($encode) {
            return base64_encode($nonce.$ciphertext);
        }
        return $nonce.$ciphertext;
    }

    /**
     * Decrypts (but does not verify) a message
     * 
     * @param string $message - ciphertext message
     * @param string $key - encryption key (raw binary expected)
     * @param boolean $encoded - are we expecting an encoded string?
     * @return string
     */
    public static function decrypt($message, $key, $encoded = false)
    {
        if ($encoded) {
            $message = base64_decode($message, true);
            if ($message === false) {
                throw new Exception('Encryption failure');
            }
        }

        $nonceSize = openssl_cipher_iv_length(self::METHOD);
        $nonce = mb_substr($message, 0, $nonceSize, '8bit');
        $ciphertext = mb_substr($message, $nonceSize, null, '8bit');

        $plaintext = openssl_decrypt(
            $ciphertext,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $nonce
        );

        return $plaintext;
    }
}

ব্যবহারের উদাহরণ

$message = 'Ready your ammunition; we attack at dawn.';
$key = hex2bin('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f');

$encrypted = UnsafeCrypto::encrypt($message, $key);
$decrypted = UnsafeCrypto::decrypt($encrypted, $key);

var_dump($encrypted, $decrypted);

ডেমো : https://3v4l.org/jl7qR


উপরের সাধারণ ক্রিপ্টো লাইব্রেরিটি এখনও ব্যবহার করা নিরাপদ নয়। আমাদের ডিক্রিপ্ট করার আগে আমাদের সিফেরটেক্সটগুলি প্রমাণীকরণ করতে হবে এবং সেগুলি যাচাই করতে হবে

দ্রষ্টব্য : ডিফল্টরূপে, UnsafeCrypto::encrypt()একটি কাঁচা বাইনারি স্ট্রিং ফিরে আসবে। আপনার যদি এটি বাইনারি-নিরাপদ বিন্যাসে (বেস 64-এনকোডড) সংরক্ষণ করতে হয় তবে এটিকে কল করুন:

$message = 'Ready your ammunition; we attack at dawn.';
$key = hex2bin('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f');

$encrypted = UnsafeCrypto::encrypt($message, $key, true);
$decrypted = UnsafeCrypto::decrypt($encrypted, $key, true);

var_dump($encrypted, $decrypted);

ডেমো : http://3v4l.org/f5K93

সাধারণ প্রমাণীকরণের আবরণ

class SaferCrypto extends UnsafeCrypto
{
    const HASH_ALGO = 'sha256';

    /**
     * Encrypts then MACs a message
     * 
     * @param string $message - plaintext message
     * @param string $key - encryption key (raw binary expected)
     * @param boolean $encode - set to TRUE to return a base64-encoded string
     * @return string (raw binary)
     */
    public static function encrypt($message, $key, $encode = false)
    {
        list($encKey, $authKey) = self::splitKeys($key);

        // Pass to UnsafeCrypto::encrypt
        $ciphertext = parent::encrypt($message, $encKey);

        // Calculate a MAC of the IV and ciphertext
        $mac = hash_hmac(self::HASH_ALGO, $ciphertext, $authKey, true);

        if ($encode) {
            return base64_encode($mac.$ciphertext);
        }
        // Prepend MAC to the ciphertext and return to caller
        return $mac.$ciphertext;
    }

    /**
     * Decrypts a message (after verifying integrity)
     * 
     * @param string $message - ciphertext message
     * @param string $key - encryption key (raw binary expected)
     * @param boolean $encoded - are we expecting an encoded string?
     * @return string (raw binary)
     */
    public static function decrypt($message, $key, $encoded = false)
    {
        list($encKey, $authKey) = self::splitKeys($key);
        if ($encoded) {
            $message = base64_decode($message, true);
            if ($message === false) {
                throw new Exception('Encryption failure');
            }
        }

        // Hash Size -- in case HASH_ALGO is changed
        $hs = mb_strlen(hash(self::HASH_ALGO, '', true), '8bit');
        $mac = mb_substr($message, 0, $hs, '8bit');

        $ciphertext = mb_substr($message, $hs, null, '8bit');

        $calculated = hash_hmac(
            self::HASH_ALGO,
            $ciphertext,
            $authKey,
            true
        );

        if (!self::hashEquals($mac, $calculated)) {
            throw new Exception('Encryption failure');
        }

        // Pass to UnsafeCrypto::decrypt
        $plaintext = parent::decrypt($ciphertext, $encKey);

        return $plaintext;
    }

    /**
     * Splits a key into two separate keys; one for encryption
     * and the other for authenticaiton
     * 
     * @param string $masterKey (raw binary)
     * @return array (two raw binary strings)
     */
    protected static function splitKeys($masterKey)
    {
        // You really want to implement HKDF here instead!
        return [
            hash_hmac(self::HASH_ALGO, 'ENCRYPTION', $masterKey, true),
            hash_hmac(self::HASH_ALGO, 'AUTHENTICATION', $masterKey, true)
        ];
    }

    /**
     * Compare two strings without leaking timing information
     * 
     * @param string $a
     * @param string $b
     * @ref https://paragonie.com/b/WS1DLx6BnpsdaVQW
     * @return boolean
     */
    protected static function hashEquals($a, $b)
    {
        if (function_exists('hash_equals')) {
            return hash_equals($a, $b);
        }
        $nonce = openssl_random_pseudo_bytes(32);
        return hash_hmac(self::HASH_ALGO, $a, $nonce) === hash_hmac(self::HASH_ALGO, $b, $nonce);
    }
}

ব্যবহারের উদাহরণ

$message = 'Ready your ammunition; we attack at dawn.';
$key = hex2bin('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f');

$encrypted = SaferCrypto::encrypt($message, $key);
$decrypted = SaferCrypto::decrypt($encrypted, $key);

var_dump($encrypted, $decrypted);

ডেমোস : কাঁচা বাইনারি , বেস 64-এনকোড


যদি কেউ এই SaferCryptoলাইব্রেরিটিকে উত্পাদন পরিবেশে বা একই ধারণাগুলির নিজস্ব প্রয়োগে ব্যবহার করতে চান তবে আমি দৃ strongly ়রূপে আপনার বাসিন্দা ক্রিপ্টোগ্রাফারের কাছে দ্বিতীয় মতামতের জন্য পৌঁছে দেওয়ার পরামর্শ দিই recommend তারা আপনাকে এমন ভুল সম্পর্কে বলতে সক্ষম করবে যা আমি হয়ত অবগত নই।

আপনি একটি নামী ক্রিপ্টোগ্রাফি লাইব্রেরি ব্যবহার করে অনেক ভাল হবে ।


3
সুতরাং, আমি কেবল অসুরক্ষিত ক্রিপ্টোকে প্রথমে কাজ করার চেষ্টা করছি। এনক্রিপশনটি ঠিকঠাক হয়, তবে প্রতিবার ডিক্রিপ্টটি চালানোর সময় আমি প্রতিক্রিয়া হিসাবে 'মিথ্যা' পাচ্ছি। আমি ডিক্রিপ্ট করার জন্য একই কী ব্যবহার করছি এবং এনকোডে পাশাপাশি ডিকোডকেও সত্য করে দিচ্ছি। উদাহরণস্বরূপ, আমি যা অনুমান করি এটি একটি টাইপো, আমি ভাবছি যে সেখান থেকেই আমার সমস্যাটি আসছে। Explain ম্যাক ভেরিয়েবলটি কোথা থেকে আসছে তা আপনি ব্যাখ্যা করতে পারেন এবং এটি কেবল $ iv হওয়া উচিত?
ডেভিড সি

1
@ ইউজেনেরিক ওপেনএসএসএল সাইফার বাস্তবায়ন সম্ভবত একমাত্র অংশ যা চুষছে না এবং এটি ভ্যানিলা পিএইচপি-র এইএস-এনআইয়ের একমাত্র উপায়। যদি আপনি ওপেনবিএসডি তে ইনস্টল করেন, পিএইচপি কোনও পার্থক্য লক্ষ্য করে পিএইচপি কোড ছাড়াই লিব্রেএসএসএল এর বিরুদ্ধে সংকলিত হবে। লিবসোডিয়াম> যে কোনও দিন ওপেনএসএসএল। এছাড়াও, libmcrypt ব্যবহার করবেন নাওপেনএসএসএল পরিবর্তে আপনি পিএইচপি বিকাশকারীদের কী ব্যবহারের পরামর্শ দিবেন?
স্কট আর্কিসজেউস্কি

2
5.2 বা 5.3 উভয়ই সমর্থিত নয় । পরিবর্তে আপনার পিএইচপি এর একটি সমর্থিত সংস্করণ , যেমন 5.6 আপডেট করার দিকে নজর দেওয়া উচিত ।
স্কট আর্কিসজেউস্কি


1
যেমন একটি বিক্ষোভের আমি এটা করেনি আপনি বাইনারি স্ট্রিং, না মানুষের readabale স্ট্রিং, আপনার কী চান
স্কট আর্কিসজেউসকি

22

ব্যবহার করুন mcrypt_encrypt()এবং mcrypt_decrypt()সংশ্লিষ্ট পরামিতি সঙ্গে। সত্যিই সহজ এবং সোজা এগিয়ে, এবং আপনি যুদ্ধ-পরীক্ষিত এনক্রিপশন প্যাকেজ ব্যবহার করেন।

সম্পাদনা

এই উত্তরের 5 বছর 4 মাস পরে, mcryptএক্সটেনশনটি এখন পিএইচপি থেকে অবচয় এবং অবশেষে অপসারণের প্রক্রিয়াধীন in


34
যুদ্ধ পরীক্ষিত এবং 8 বছরের বেশি সময় আপডেট করা হয়নি?
মার্টেন বোদেউয়েস

2
ওয়েল, এমক্রিপ্ট পিএইচপি 7 এ রয়েছে এবং অবহেলিত নয় - এটি আমার পক্ষে যথেষ্ট ভাল। সমস্ত কোড ওপেনএসএসএল এর ভয়ঙ্কর মানের নয় এবং প্রতি কয়েকদিনে প্যাচিংয়ের প্রয়োজন।
ইউজেন রিয়েক

3
সমর্থন করার ক্ষেত্রে এমক্রিপ্ট কেবল ভয়াবহ নয়। এটি পিকেসিএস # 7 কমপ্লায়েন্ট প্যাডিং, প্রমাণীকৃত এনক্রিপশনগুলির মতো সেরা অনুশীলনগুলিও প্রয়োগ করে না। এটি SHA-3 বা অন্য কোনও নতুন অ্যালগরিদম সমর্থন করবে না কারণ কেউ এটি রক্ষণাবেক্ষণ করছে না, আপনাকে আপগ্রেডের পথে ছিনিয়ে নিচ্ছে। তদুপরি এটি আংশিক কীগুলি, জিরো প্যাডিং সম্পাদন ইত্যাদির মতো জিনিস গ্রহণ করত it পিএইচপি থেকে ধীরে ধীরে অপসারণের প্রক্রিয়ায় এটির একটি ভাল কারণ রয়েছে।
মার্টেন বোদেউয়েস

2
পিএইচপি 7.1 এ, সমস্ত এমক্রিপ্ট_ * ফাংশন একটি E_DEPRECATED বিজ্ঞপ্তি উত্থাপন করবে। পিএইচপি .1.১ + ১ (এটি 7.২ বা ৮.০ হোক), এমক্রিপ্ট এক্সটেনশানটি মূল থেকে দূরে এবং পিইসিএলে স্থানান্তরিত হবে, যেখানে সত্যই এটি ইনস্টল করতে চান এমন লোকেরা যদি এখনও পিইসিএল থেকে পিএইচপি এক্সটেনশন ইনস্টল করতে পারে তবে এটি করতে পারে।
ম্লাদেন জঞ্জেটভিক

4

পিএইচপি 7.2 সম্পূর্ণ দূরে সরে গেছেMcrypt এবং এনক্রিপশন এখন রক্ষণাবেক্ষণযোগ্য Libsodiumলাইব্রেরির উপর ভিত্তি করে ।

আপনার সমস্ত এনক্রিপশন প্রয়োজনীয়তা মূলত Libsodiumগ্রন্থাগারের মাধ্যমে সমাধান করা যেতে পারে ।

// On Alice's computer:
$msg = 'This comes from Alice.';
$signed_msg = sodium_crypto_sign($msg, $secret_sign_key);


// On Bob's computer:
$original_msg = sodium_crypto_sign_open($signed_msg, $alice_sign_publickey);
if ($original_msg === false) {
    throw new Exception('Invalid signature');
} else {
    echo $original_msg; // Displays "This comes from Alice."
}

লিবসডিয়াম ডকুমেন্টেশন: https://github.com/paragonie/pecl-libsium-doc


2
আপনি যদি কিছু কোড পেস্ট করেন তবে নিশ্চিত করুন যে সমস্ত ভেরিয়েবলগুলি কভার হয়েছে। আপনার উদাহরণ $ secret_sign_key এবং $ alice_sign_publickey সালে শূন্য হয়
undefinedman

1
crypto_signএপিআই করে না এনক্রিপ্ট বার্তা - যে এক প্রয়োজন হবে crypto_aead_*_encryptফাংশন।
রজার ডিউক

1

গুরুত্বপূর্ণ এই উত্তরটি কেবল পিএইচপি 5 এর জন্য বৈধ, পিএইচপি 7-তে বিল্ট-ইন ক্রিপ্টোগ্রাফিক ফাংশন ব্যবহার করুন।

এখানে সহজ তবে যথেষ্ট বাস্তবায়ন নিরাপদ:

  • সিবিসি মোডে AES-256 এনক্রিপশন
  • প্লেইন-পাঠ্য পাসওয়ার্ডের বাইরে এনক্রিপশন কী তৈরি করতে PBKDF2
  • এনক্রিপ্ট করা বার্তাটি প্রমাণীকরণের জন্য এইচএমএসি।

কোড এবং উদাহরণগুলি এখানে: https://stackoverflow.com/a/19445173/1387163


1
আমি কোনও ক্রিপ্টোগ্রাফি বিশেষজ্ঞ নই, তবে সরাসরি পাসওয়ার্ড থেকে চাবি নেওয়া ভয়ানক ধারণা বলে মনে হচ্ছে। রেইনবো টেবিল + দুর্বল পাসওয়ার্ড এবং চলে গেছে আপনার সুরক্ষা। এছাড়াও আপনার লিংক পয়েন্টটি এমক্রিপ্ট ফাংশনগুলিতে, যেগুলি পিএইচপি
since.১

@ আল্ফ.দেভ আপনি ঠিক করেছেন যে উপরের উত্তরটি কেবল পিএইচপি 5
ইউজিন ফিদেলিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.