2012-08-08 8 views
17

पर एन्क्रिप्शन मैं सी # में कुछ (कुकी) डेटा एन्क्रिप्ट करने की कोशिश कर रहा हूं और फिर इसे PHP में डिक्रिप्ट कर रहा हूं। मैंने रिजेंडेल एन्क्रिप्शन का उपयोग करना चुना है। मुझे लगभग काम मिल गया है, सिवाय इसके कि पाठ का केवल एक भाग डिक्रिप्ट किया गया है! मैं इस उदाहरण से काम शुरू कर दिया:सी # PHP डिक्रिप्शन

{"DisplayName":"xxx", "Username": "yyy", "EmailAddress":"zzz"} 

तो मैं जो बनाता है/सी # अनुप्रयोग के लिए लॉग इन संग्रहीत से कुकी को कूटबद्ध: Decrypt PHP encrypted string in C#

यहाँ पाठ (JSON) है कि मैं एनक्रिप्ट करने कर रहा हूँ (संवेदनशील जानकारी हटा दिए गए) है कुंजी और चतुर्थ और फिर PHP एप पर रीडायरेक्ट करता है जिसे कुकी को डिक्रिप्ट/पढ़ने के लिए माना जाता है। जब मैं कुकी डिक्रिप्ट, तो वह ऐसा बाहर आता है:

{"DisplayName":"xxx","F�A ;��HP=D�������4��z����ť���k�#E���R�j�5�\�t. t�D��" 

अद्यतन: मैं एक छोटा सा आगे मिल गया है और यह अब परिणाम

string(96) "{"DisplayName":"xxx","Username":"yyy","EmailAddress"�)ق��-�J��k/VV-v� �9�B`7^" 

आप देख सकते हैं है , यह इसे डिक्रिप्ट करना शुरू कर देता है, लेकिन फिर गड़बड़ हो जाता है ...

स्ट्रिंग डिक्रिप्ट करते समय यह सही हो जाता है (पैडिंग के साथ, जिसमें मेरे पास रीमोव के लिए एक फ़ंक्शन है ई गद्दी), लेकिन अगर मैं एक वर्ण परीक्षण स्ट्रिंग बदल रहा कचरा फिर से मिलता है:

अद्यतन:

B�nHL�Ek �¿?�UΣlO����OЏ�M��NO/�f.M���Lƾ�CC�Y>F��~�qd�+ 

यहाँ मैं यादृच्छिक कुंजी और चतुर्थ उत्पन्न करने के लिए उपयोग करें सी # कोड है: मैं तो बस अब के लिए स्थिर कुंजी/चतुर्थ उपयोग कर रहा हूँ, यहाँ वे हैं:

Key: lkirwf897+22#bbtrm8814z5qq=498j5 
IV: 741952hheeyy66#[email protected] 

RijndaelManaged symmetricKey = new RijndaelManaged(); 
symmetricKey.BlockSize = 256; 
symmetricKey.KeySize = 256; 
symmetricKey.Padding = PaddingMode.Zeros; 
symmetricKey.Mode = CipherMode.CBC; 
string key = Convert.ToBase64String(symmetricKey.Key); 
string IV = Convert.ToBase64String(symmetricKey.IV); 

फिर मैं एन्कोडिंग/डिकोडिंग के लिए बाद में पुनर्प्राप्त करने के लिए कुंजी और IV को डेटाबेस में सहेजता हूं।

यह पूर्ण एन्क्रिप्शन वर्ग है:

public static class Encryption 
    { 
     public static string Encrypt(string prm_text_to_encrypt, string prm_key, string prm_iv) 
     { 
      var sToEncrypt = prm_text_to_encrypt; 

      var rj = new RijndaelManaged() 
      { 
       Padding = PaddingMode.PKCS7, 
       Mode = CipherMode.CBC, 
       KeySize = 256, 
       BlockSize = 256, 
       //FeedbackSize = 256 
      }; 

      var key = Encoding.ASCII.GetBytes(prm_key); 
      var IV = Encoding.ASCII.GetBytes(prm_iv); 
      //var key = Convert.FromBase64String(prm_key); 
      //var IV = Convert.FromBase64String(prm_iv); 

      var encryptor = rj.CreateEncryptor(key, IV); 

      var msEncrypt = new MemoryStream(); 
      var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write); 

      var toEncrypt = Encoding.ASCII.GetBytes(sToEncrypt); 

      csEncrypt.Write(toEncrypt, 0, toEncrypt.Length); 
      csEncrypt.FlushFinalBlock(); 

      var encrypted = msEncrypt.ToArray(); 

      return (Convert.ToBase64String(encrypted)); 
     } 

     public static string Decrypt(string prm_text_to_decrypt, string prm_key, string prm_iv) 
     { 

      var sEncryptedString = prm_text_to_decrypt; 

      var rj = new RijndaelManaged() 
      { 
       Padding = PaddingMode.PKCS7, 
       Mode = CipherMode.CBC, 
       KeySize = 256, 
       BlockSize = 256, 
       //FeedbackSize = 256 
      }; 

      var key = Encoding.ASCII.GetBytes(prm_key); 
      var IV = Encoding.ASCII.GetBytes(prm_iv); 
      //var key = Convert.FromBase64String(prm_key); 
      //var IV = Convert.FromBase64String(prm_iv); 

      var decryptor = rj.CreateDecryptor(key, IV); 

      var sEncrypted = Convert.FromBase64String(sEncryptedString); 

      var fromEncrypt = new byte[sEncrypted.Length]; 

      var msDecrypt = new MemoryStream(sEncrypted); 
      var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read); 

      csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length); 

      return (Encoding.ASCII.GetString(fromEncrypt)); 
     } 

     public static void GenerateKeyIV(out string key, out string IV) 
     { 
      var rj = new RijndaelManaged() 
      { 
       Padding = PaddingMode.PKCS7, 
       Mode = CipherMode.CBC, 
       KeySize = 256, 
       BlockSize = 256, 
       //FeedbackSize = 256 
      }; 
      rj.GenerateKey(); 
      rj.GenerateIV(); 

      key = Convert.ToBase64String(rj.Key); 
      IV = Convert.ToBase64String(rj.IV); 
     } 
    } 

यहाँ PHP कोड मैं डेटा को डिक्रिप्ट करने का उपयोग कर रहा है:

function decryptRJ256($key,$iv,$string_to_decrypt) 
{ 
    $string_to_decrypt = base64_decode($string_to_decrypt); 
    $rtn = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $string_to_decrypt, MCRYPT_MODE_CBC, $iv); 
    //$rtn = rtrim($rtn, "\0\4"); 
    $rtn = unpad($rtn); 
    return($rtn); 
} 

function unpad($value) 
{ 
    $blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); 
    //apply pkcs7 padding removal 
    $packing = ord($value[strlen($value) - 1]); 
    if($packing && $packing < $blockSize){ 
     for($P = strlen($value) - 1; $P >= strlen($value) - $packing; $P--){ 
      if(ord($value{$P}) != $packing){ 
       $packing = 0; 
      }//end if 
     }//end for 
    }//end if 

    return substr($value, 0, strlen($value) - $packing); 
} 

$ky = 'lkirwf897+22#bbtrm8814z5qq=498j5'; // 32 * 8 = 256 bit key 
$iv = '741952hheeyy66#[email protected]'; // 32 * 8 = 256 bit iv 

$enc = $_COOKIE["MyCookie"]; 

$dtext = decryptRJ256($ky, $iv, $enc); 
var_dump($dtext); 

मैं इस हिस्से के बारे में थोड़ा अनिश्चित हूं, के सभी क्योंकि मैंने जो उदाहरण कोड देखा है वह बस बेस 64 एन्कोडेड स्ट्रिंग में सीधे डिक्रिप्टर पर गुजरता है, लेकिन मेरे उदाहरण में, मुझे इसे पास करने से पहले इसे 6464 डीकोड करना होगा अन्यथा मुझे त्रुटि मिलती है कि कुंजी और IV सही लंबाई नहीं हैं।

अद्यतन: मैं PHP द्वारा आवश्यक प्रारूप में ASCII कुंजी का उपयोग कर रहा हूं। अगर मैं रिजेंडेल प्रबंधित वर्ग से चाबियाँ उत्पन्न करता हूं तो वे PHP पक्ष पर काम नहीं करते हैं, लेकिन मैं उन चाबियों का उपयोग कर सकता हूं जो PHP पक्ष पर काम करने के लिए जाने जाते हैं और उन्हें रिजेंडेल मैनेज्ड सी # पक्ष में उपयोग करते हैं।

अगर मुझे कोई प्रासंगिक जानकारी छोड़ दी गई तो कृपया मुझे बताएं। TIA!

+2

मैं याद करने के लिए आप इस प्राप्त कर सकते हैं कि यदि चतुर्थ आप डिक्रिप्ट करने के लिए आपूर्ति गलत – pm100

+0

इसके बिना काम करता है लगता है चतुर्थ? –

+0

यदि मैं IV शामिल नहीं करता तो यह काम नहीं करता है। – solidau

उत्तर

5

चूंकि स्ट्रिंग आंशिक रूप से ठीक है, लेकिन अंत में गड़बड़ी है, यह एन्क्रिप्शन के भीतर एक पैडिंग समस्या का सुझाव देगा जो 256 बाइट्स के सटीक ब्लॉक की अपेक्षा करता है। मैं पीकेसीएस 7 (पैडिंगमोड.पीकेसीएस 7) के बजाय पैडिंग को सी # पक्ष पर जेरोस पर सेट करने का सुझाव देता हूं जो PHP बिना किसी समस्या के समझ जाएगा (क्योंकि यह उस पार्सर पर डिफ़ॉल्ट मोड है)।

संपादित करें: ओह, मैं नोटिस नहीं किया है कि आप अपने PHP में निम्नलिखित था:

$enc = $_COOKIE["MyCookie"]; 

यह चेतावनी है। PHP को एन्क्रिप्टेड डेटा को उतना ही नहीं मिल रहा है और कुछ urldecode sanitizing चला रहा है। आपको यह चर यह देखने के लिए प्रिंट करना चाहिए कि यह वास्तव में सी # कोड से भेजे जा रहे कार्यों से मेल खाता है।

EDIT2:

इस जोड़कर कुकी से लापता + अक्षरों तक व्हाइटस्पेस कन्वर्ट:

str_replace(' ', '+', $enc); 
+0

मैंने इसे बदल दिया है, लेकिन अभी भी एक समस्या है ... मैं केवल एक विशेष स्ट्रिंग को एन्कोड/डीकोड कर सकता हूं! मेरे पास एक JSON स्ट्रिंग है जिसे मैं परीक्षण के लिए उपयोग कर रहा हूं, और अंततः मुझे इसे डिक्रिप्ट करने के लिए मिला। तो फिर मैं कुछ अन्य तारों का परीक्षण करने गया, अगर मैं अपनी टेस्ट स्ट्रिंग में 1 अक्षर भी बदलता हूं, तो यह टूट जाता है ... कृपया कुछ मिनटों में अपना कोड अपडेट देखें .... – solidau

+0

स्ट्रिंग्स थोड़ा अलग हैं, PHP पक्ष "+" गायब है ... – solidau

+1

बाद में इसे पढ़ने वाले लोगों के लिए, मुझे कुछ टिप्पणियों को बीच में हटाना पड़ा .... मूल रूप से, जब स्ट्रिंग को कुकी से PHP पर भेजा गया था, तो PHP स्ट्रिंग और प्रतिस्थापित करेगा अंतरिक्ष के साथ "+" अक्षर " – solidau

18

भावी पीढ़ी के लिए मैं यहाँ पूरी तरह से पूरा समाधान रखने कर रहा हूँ।

सी # एन्क्रिप्शन कक्षा

public static class Encryption 
{ 
    public static string Encrypt(string prm_text_to_encrypt, string prm_key, string prm_iv) 
    { 
     var sToEncrypt = prm_text_to_encrypt; 

     var rj = new RijndaelManaged() 
     { 
      Padding = PaddingMode.PKCS7, 
      Mode = CipherMode.CBC, 
      KeySize = 256, 
      BlockSize = 256, 
     }; 

     var key = Convert.FromBase64String(prm_key); 
     var IV = Convert.FromBase64String(prm_iv); 

     var encryptor = rj.CreateEncryptor(key, IV); 

     var msEncrypt = new MemoryStream(); 
     var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write); 

     var toEncrypt = Encoding.ASCII.GetBytes(sToEncrypt); 

     csEncrypt.Write(toEncrypt, 0, toEncrypt.Length); 
     csEncrypt.FlushFinalBlock(); 

     var encrypted = msEncrypt.ToArray(); 

     return (Convert.ToBase64String(encrypted)); 
     } 

    public static string Decrypt(string prm_text_to_decrypt, string prm_key, string prm_iv) 
    { 

     var sEncryptedString = prm_text_to_decrypt; 

     var rj = new RijndaelManaged() 
     { 
      Padding = PaddingMode.PKCS7, 
      Mode = CipherMode.CBC, 
      KeySize = 256, 
      BlockSize = 256, 
     }; 

     var key = Convert.FromBase64String(prm_key); 
     var IV = Convert.FromBase64String(prm_iv); 

     var decryptor = rj.CreateDecryptor(key, IV); 

     var sEncrypted = Convert.FromBase64String(sEncryptedString); 

     var fromEncrypt = new byte[sEncrypted.Length]; 

     var msDecrypt = new MemoryStream(sEncrypted); 
     var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read); 

     csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length); 

     return (Encoding.ASCII.GetString(fromEncrypt)); 
     } 

    public static void GenerateKeyIV(out string key, out string IV) 
    { 
     var rj = new RijndaelManaged() 
     { 
      Padding = PaddingMode.PKCS7, 
      Mode = CipherMode.CBC, 
      KeySize = 256, 
      BlockSize = 256, 
     }; 
     rj.GenerateKey(); 
     rj.GenerateIV(); 

     key = Convert.ToBase64String(rj.Key); 
     IV = Convert.ToBase64String(rj.IV); 
    } 
} 

पीएचपी डिक्रिप्शन स्निपेट

<?php 
function decryptRJ256($key,$iv,$encrypted) 
{ 
    //PHP strips "+" and replaces with " ", but we need "+" so add it back in... 
    $encrypted = str_replace(' ', '+', $encrypted); 

    //get all the bits 
    $key = base64_decode($key); 
    $iv = base64_decode($iv); 
    $encrypted = base64_decode($encrypted); 

    $rtn = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, MCRYPT_MODE_CBC, $iv); 
    $rtn = unpad($rtn); 
    return($rtn); 
} 

//removes PKCS7 padding 
function unpad($value) 
{ 
    $blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); 
    $packing = ord($value[strlen($value) - 1]); 
    if($packing && $packing < $blockSize) 
    { 
     for($P = strlen($value) - 1; $P >= strlen($value) - $packing; $P--) 
     { 
      if(ord($value{$P}) != $packing) 
      { 
       $packing = 0; 
      } 
     } 
    } 

    return substr($value, 0, strlen($value) - $packing); 
} 
?> 
<pre> 
<?php 

$enc = $_COOKIE["MyCookie"]; 

$ky = ""; //INSERT THE KEY GENERATED BY THE C# CLASS HERE 
$iv = ""; //INSERT THE IV GENERATED BY THE C# CLASS HERE 

$json_user = json_decode(decryptRJ256($ky, $iv, $enc), true); 

var_dump($json_user); 

?> 
+0

मुझे सी # कोड को बदलना है: var एन्कोडिंग = नया यूटीएफ 8 एन्कोडिंग(); var key = एन्कोडिंग। गेटबाइट्स (prm_key); var IV = एन्कोडिंग। गेटबाइट्स (prm_iv); मुझे Convert.FromBase64String (prm_iv) का उपयोग करके विनियमित "prm_iv" उत्पन्न करने का कोई तरीका नहीं मिला, फिर मैंने एन्कोडिंग .ASCII.GetBytes को आजमाया और मैं कुंजी उत्पन्न कर सकता था लेकिन PHP से सही परिणाम नहीं मिला। इसलिए मैंने उसी संदर्भ में एक अन्य प्रश्न/उत्तरदाता में ठोकर खाई, मैंने यूटीएफ 8 एन्कोडिंग से गेटबाइट्स की कोशिश की और आखिरकार काम किया। सभी को धन्यवाद। –

+0

आकर्षण, सी # 4.0 और PHP 5.4x जैसे काम करता है, धन्यवाद सर :) –

संबंधित मुद्दे