CryptoJs - PHP और जावास्क्रिप्ट द्वारा एन्क्रिप्ट / डिक्रिप्ट - सरल आउटपुट एन्क्रिप्टेड स्ट्रिंग

Sep 23 2020

मैं Php और Javascript में कुछ स्ट्रिंग को एन्क्रिप्ट और डिक्रिप्ट करना चाहता हूं और वेब पर देखते हुए, सबसे अच्छा और सुरक्षित तरीका CryptoJs लगता है।

यह पोस्ट PHP के साथ Encrypt, जावास्क्रिप्ट के साथ डिक्रिप्ट (क्रिप्टोज) का डुप्लिकेट नहीं है क्योंकि आउटपुट स्ट्रिंग यह सरल नहीं है।

यह मेरा कोड है लेकिन Js डिक्रिप्टिंग कोड काम नहीं करता है। यह क्या गलत है?

<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
    </head>
    <body>
        <p>--- PHP ------------------</p>
    
        <?php
            function myCrypt($value, $passphrase, $iv){ $encrypted_data = openssl_encrypt($value, 'aes-256-cbc', $passphrase, true, $iv); return base64_encode($encrypted_data);
            }
            
            function myDecrypt($value, $passphrase, $iv){ $value = base64_decode($value); $data = openssl_decrypt($value, 'aes-256-cbc', $passphrase, true, $iv); return $data;
            }
            

            $valTxt="MyText"; $pswd="MyPassword";
            $vector="1234567890123412"; $encrypted = myCrypt($valTxt, $pswd, $vector); $decrypted = myDecrypt($encrypted, $pswd, $vector); echo "<p>Text to crypt --------> ".$valTxt." </p>";
            echo "<p>Password: ".$pswd." </p>"; echo "<p>Vector: ".$vector." </p>";
            echo "<p>TextEncrypt: ".$encrypted." </p>"; echo "<p>TextDecrypt: ".$decrypted." </p>";
        ?>
        
        <br><br><br>
        <p>--- Javascript ------------------</p>
        <p>JS-DataEncrypt: --------- <span id="DataEncrypt"></span></p>
        <p>JS-DataPassword: -------- <span id="DataPassword"></span></p>
        <p>JS-DataVector: ---------- <span id="DataVector"></span></p>
        <p>JS-TextDecrypted: ------- <span id="result"></span></p>
        
        <script>
            var DataEncrypt='<?php echo $encrypted;?>'; var DataPassword='<?php echo $pswd;?>';
            var DataVector='<?php echo $vector;?>';
            
            //var key = CryptoJS.enc.Hex.parse(DataPassword);
            //var iv = CryptoJS.enc.Hex.parse(DataVector);
            //var decrypted = CryptoJS.AES.decrypt(DataEncrypt, key, { iv: iv });
            
            var decrypted = CryptoJS.AES.decrypt(DataEncrypt, DataPassword, { iv: DataVector });
            
            decrypted= CryptoJS.enc.Utf8.stringify(decrypted)
            
            
            
            document.getElementById("DataEncrypt").innerHTML = DataEncrypt;
            document.getElementById("DataPassword").innerHTML = DataPassword;
            document.getElementById("DataVector").innerHTML = DataVector;
            document.getElementById("result").innerHTML = decrypted;
        </script>
    
    
        
    </body>
</html>

पुनश्च बेहतर है अगर आउटपुट स्ट्रिंग ($ एन्क्रिप्टेड) ​​16 अंकों का ए-ज़ा-ज़0-9 होगा ... क्या यह संभव है 'एईएस -255-सीबीसी' को बदलना?

जवाब

3 Topaco Sep 23 2020 at 03:21

PHP कोड में निम्नलिखित पर विचार किया जाना चाहिए:

  • $passphraseपासफ़्रेज़ को निरूपित नहीं करता है, लेकिन कुंजी। चुनाव के लिए इस कुंजी का आकार 32 बाइट होना चाहिए aes-256-cbc। यदि यह बहुत छोटा है, तो यह 0 मानों से भरा है, यदि यह बहुत लंबा है, तो इसे काट दिया जाता है। यह त्रुटि का एक सामान्य स्रोत है, इसलिए 32 बाइट की कुंजी का उपयोग किया जाना चाहिए। यदि आप पासफ़्रेज़ के साथ काम करना चाहते हैं, तो आपको एक केडीएफ (जैसे पीबीकेडीएफ 2) का उपयोग करना होगा।
  • चौथे पैरामीटर में झंडे सेट किए जाते हैं, और बूलियन अभिव्यक्ति (जैसे true) नहीं होती है। यदि डेटा को बाइनरी रूप में वापस किया जाना चाहिए, तो OPENSSL_RAW_DATAध्वज को सेट किया जाना चाहिए।
  • स्टेटिक IVs असुरक्षित हैं, आमतौर पर प्रत्येक एन्क्रिप्शन के लिए एक नया IV उत्पन्न होता है, जिसे प्राप्तकर्ता को सिफरटेक्स्ट के साथ भेजा जाता है। चूंकि IV गुप्त नहीं है, यह आमतौर पर एन्क्रिप्शन के बिना बाइट स्तर पर सिफरटेक्स्ट के सामने रखा जाता है।

निम्नलिखित नमूना PHP कोड (पोस्ट कोड के आधार पर):

function myCrypt($value, $key, $iv){
    $encrypted_data = openssl_encrypt($value, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
    return base64_encode($encrypted_data); } function myDecrypt($value, $key, $iv){
    $value = base64_decode($value);
    $data = openssl_decrypt($value, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
    return $data; } $valTxt="MyText";
$key="01234567890123456789012345678901"; // 32 bytes $vector="1234567890123412"; // 16 bytes
$encrypted = myCrypt($valTxt, $key, $vector);
$decrypted = myDecrypt($encrypted, $key, $vector);
print($encrypted . "\n"); print($decrypted . "\n");

निम्न परिणाम देता है:

1SF+kez1CE5Rci3H6ff8og==
MyText

डिक्रिप्शन के लिए इसी CryptoJS कोड है:

var DataEncrypt = "1SF+kez1CE5Rci3H6ff8og==";
var DataKey = CryptoJS.enc.Utf8.parse("01234567890123456789012345678901");
var DataVector = CryptoJS.enc.Utf8.parse("1234567890123412");
var decrypted = CryptoJS.AES.decrypt(DataEncrypt, DataKey, { iv: DataVector });        
var decrypted = CryptoJS.enc.Utf8.stringify(decrypted);
console.log(decrypted);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

आउटपुट के साथ MyTextजो मूल प्लेनटेक्स्ट से मेल खाता है।

यह महत्वपूर्ण है कि कुंजी को पास कर दिया WordArrayजाए, ताकि यह कुंजी के रूप में व्याख्या की जाए और पासफ़्रेज़ के रूप में नहीं। रूपांतरण के लिए CryptoJS एन्कोडर (जैसे CryptoJS.enc.Utf8) प्रदान करता है ।


अंत में आपके प्रश्न के बारे में: सिफरटेक्स्ट्स द्विआधारी मनमाना अनुक्रम हैं जिन्हें विशेष बाइनरी-टू-टेक्स्ट एन्कोडिंग (जैसे बेस 64 इस मामले में, या हेक्साडेसिमल) के साथ एक स्ट्रिंग में परिवर्तित किया जा सकता है, जो आम तौर पर कच्चे डेटा (बेस 64: से अधिक होता है) 75% दक्षता, हेक्साडेसिमल: 50% दक्षता, यहां देखें )।
ब्लॉक आकार (जैसे एईएस के लिए 16 बाइट्स) के बराबर अल्फ़ान्यूमेरिक वर्ण (जैसे 16 वर्ण) की एक संख्या के साथ एक सिफरटेक्स्ट ब्लॉक का प्रतिनिधित्व इसलिए आमतौर पर संभव नहीं है।
ध्यान दें कि एक वर्ण सेट एन्कोडिंग के साथ एक स्ट्रिंग में परिवर्तित करना जैसे कि UTF8 एक समाधान भी नहीं है, लेकिन डेटा को दूषित करेगा।