2013-10-05 4 views
15

मैं एईएस-128 सीबीसी का उपयोग कर स्ट्रिंग को डिक्रिप्ट करने का प्रयास कर रहा हूं जिसे मूल रूप से जावा एईएस एन्क्रिप्शन का उपयोग करके क्रिप्ट किया गया था। जावा पीकेसीएस 7 पैडिंग में प्रयोग किया जाता है। और मैंने समान PHP कोड का उपयोग करके एन्क्रिप्ट और डिक्रिप्ट करने का प्रयास किया है। लेकिन मुझे अलग-अलग परिणाम मिल रहे हैं।PHP में एईएस 128 एन्क्रिप्शन PHP

मेरे जावा कोड

import java.security.MessageDigest; 
import java.security.spec.AlgorithmParameterSpec; 

import javax.crypto.Cipher; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 

import android.util.Base64; 

/** 
* @author vipin.cb , [email protected] <br> 
*   Sep 27, 2013, 5:18:34 PM <br> 
*   Package:- <b>com.veebow.util</b> <br> 
*   Project:- <b>Veebow</b> 
*   <p> 
*/ 
public class AESCrypt { 

    private final Cipher cipher; 
    private final SecretKeySpec key; 
    private AlgorithmParameterSpec spec; 
    public static final String SEED_16_CHARACTER = "U1MjU1M0FDOUZ.Qz"; 

    public AESCrypt() throws Exception { 
     // hash password with SHA-256 and crop the output to 128-bit for key 
     MessageDigest digest = MessageDigest.getInstance("SHA-256"); 
     digest.update(SEED_16_CHARACTER.getBytes("UTF-8")); 
     byte[] keyBytes = new byte[32]; 
     System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length); 

     cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); 
     key = new SecretKeySpec(keyBytes, "AES"); 
     spec = getIV(); 
    } 

    public AlgorithmParameterSpec getIV() { 
     byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; 
     IvParameterSpec ivParameterSpec; 
     ivParameterSpec = new IvParameterSpec(iv); 

     return ivParameterSpec; 
    } 

    public String encrypt(String plainText) throws Exception { 
     cipher.init(Cipher.ENCRYPT_MODE, key, spec); 
     byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8")); 
     String encryptedText = new String(Base64.encode(encrypted, 
       Base64.DEFAULT), "UTF-8"); 

     return encryptedText; 
    } 

    public String decrypt(String cryptedText) throws Exception { 
     cipher.init(Cipher.DECRYPT_MODE, key, spec); 
     byte[] bytes = Base64.decode(cryptedText, Base64.DEFAULT); 
     byte[] decrypted = cipher.doFinal(bytes); 
     String decryptedText = new String(decrypted, "UTF-8"); 

     return decryptedText; 
    } 

} 

और मैं उपयोग कर रहा हूँ बराबर PHP कोड।

<?php 

class MCrypt { 

    private $iv = '0000000000000000'; #Same as in JAVA    
    private $key = 'U1MjU1M0FDOUZ.Qz'; #Same as in JAVA 

    function __construct() { 
     $this->key = hash('sha256', $this->key, true); 
    } 

    function encrypt($str) { 
     $iv = $this->iv; 
     $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); 
     mcrypt_generic_init($td, $this->key, $iv); 
     $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
     $pad = $block - (strlen($str) % $block); 
     $str .= str_repeat(chr($pad), $pad); 
     $encrypted = mcrypt_generic($td, $str); 
     mcrypt_generic_deinit($td); 
     mcrypt_module_close($td); 
     return base64_encode($encrypted); 
    } 

    function decrypt($code) { 
     $iv = $this->iv; 
     $td = mcrypt_module_open('rijndael-128', '', 'cbc', ''); 
     mcrypt_generic_init($td, $this->key, $iv); 
     $str = mdecrypt_generic($td, base64_decode($code)); 
     $block = mcrypt_get_block_size('rijndael-128', 'cbc'); 
     mcrypt_generic_deinit($td); 
     mcrypt_module_close($td); 
     return $str; 
     //return $this->strippadding($str);    
    } 

    /* 
     For PKCS7 padding 
    */ 
    private function addpadding($string, $blocksize = 16) { 
     $len = strlen($string); 
     $pad = $blocksize - ($len % $blocksize); 
     $string .= str_repeat(chr($pad), $pad); 
     return $string; 
    } 

    private function strippadding($string) { 
     $slast = ord(substr($string, -1)); 
     $slastc = chr($slast); 
     $pcheck = substr($string, -$slast); 
     if (preg_match("/$slastc{" . $slast . "}/", $string)) { 
      $string = substr($string, 0, strlen($string) - $slast); 
      return $string; 
     } else { 
      return false; 
     } 
    } 

} 

$encryption = new MCrypt(); 
echo $encryption->encrypt('123456') . "<br/>"; 
echo $encryption->decrypt('tpyxISJ83dqEs3uw8bN/+w=='); 

जावा
सादे पाठ में = 123456
सिफर पाठ = tpyxISJ83dqEs3uw8bN/+ w ==

PHP में

सादा पाठ = 123456
सिफर पाठ = IErqfTCktrnmWndOpq3pnQ ==

जब मैंने जावा एन्क्रिप्टेड टेक्स्ट "tpyxISJ83dqEs3uw8bN/+ w ==" को PHP डिक्रिप्शन का उपयोग करके डीक्रिप्ट करने का प्रयास किया तो मैं ge हूँ यदि मैंने पैडिंग हटा दी तो एक खाली सरणी को टिंग करना। पैडिंग को हटाने के बिना मुझे ":::::::::::

मुझे लगता है कि PHP और जावा में उपयोग किए गए चतुर्थ बाइट्स के साथ कुछ गलती है। क्या कोई इस पर मेरी सहायता कर सकता है। मैंने कई संयोजनों की कोशिश की है। अभी भी कोई परिणाम नहीं है। मैं जावा अवधारणाओं के लिए बहुत नया हूँ।

------ समाधान -------

मैं owlstead द्वारा दिए गए टिप्पणियों के अनुसार मेरी php वर्ग संशोधित किया है। एक बेहतर तरीका हो सकता है। मैं इसे यहां पोस्ट कर रहा हूं ताकि किसी को भविष्य में यह सहायक हो सके और आगे की सुधार के लिए आपकी टिप्पणियों का स्वागत है। (यदि आप ASCII या UTF-8 एन्कोडिंग अनुमान)

<?php 

class MCrypt { 

    private $hex_iv = '00000000000000000000000000000000'; # converted Java byte code in to HEX and placed it here    
    private $key = 'U1MjU1M0FDOUZ.Qz'; #Same as in JAVA 

    function __construct() { 
     $this->key = hash('sha256', $this->key, true); 
     //echo $this->key.'<br/>'; 
    } 

    function encrypt($str) {  
     $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); 
     mcrypt_generic_init($td, $this->key, $this->hexToStr($this->hex_iv)); 
     $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
     $pad = $block - (strlen($str) % $block); 
     $str .= str_repeat(chr($pad), $pad); 
     $encrypted = mcrypt_generic($td, $str); 
     mcrypt_generic_deinit($td); 
     mcrypt_module_close($td);   
     return base64_encode($encrypted); 
    } 

    function decrypt($code) {   
     $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); 
     mcrypt_generic_init($td, $this->key, $this->hexToStr($this->hex_iv)); 
     $str = mdecrypt_generic($td, base64_decode($code)); 
     $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
     mcrypt_generic_deinit($td); 
     mcrypt_module_close($td);   
     return $this->strippadding($str);    
    } 

    /* 
     For PKCS7 padding 
    */ 

    private function addpadding($string, $blocksize = 16) { 
     $len = strlen($string); 
     $pad = $blocksize - ($len % $blocksize); 
     $string .= str_repeat(chr($pad), $pad); 
     return $string; 
    } 

    private function strippadding($string) { 
     $slast = ord(substr($string, -1)); 
     $slastc = chr($slast); 
     $pcheck = substr($string, -$slast); 
     if (preg_match("/$slastc{" . $slast . "}/", $string)) { 
      $string = substr($string, 0, strlen($string) - $slast); 
      return $string; 
     } else { 
      return false; 
     } 
    } 
function hexToStr($hex) 
{ 
    $string=''; 
    for ($i=0; $i < strlen($hex)-1; $i+=2) 
    { 
     $string .= chr(hexdec($hex[$i].$hex[$i+1])); 
    } 
    return $string; 
} 
} 

$encryption = new MCrypt(); 
echo $encryption->encrypt('123456') . "<br/>"; 
echo $encryption->decrypt('tpyxISJ83dqEs3uw8bN/+w=='); 
+0

धन्यवाद। यही वह है जिसकी तलाश में मैं हूं। मेरी कुंजी और presto magico में एक टाइपो तय! – ssdscott

+0

@ssdscott मुझे खुशी है कि यह 2 साल पहले पोस्ट करने के बाद भी आपकी मदद करता है :) – shanavascet

उत्तर

9

आपका चतुर्थ अलग है, शून्य मान के साथ एक बाइट एक चरित्र '0' जो हेक्साडेसिमल में मूल्य 30 या 48 दशमलव के साथ एक बाइट में अनुवाद होगा से अलग है।

+0

IV क्या होना चाहिए .. मैंने भाग्य के बिना IV के लिए 16 स्थान दिए हैं। मैंने बाइट iv को जावा में स्ट्रिंग करने की कोशिश की और लंबाई 16 के साथ खाली स्ट्रिंग प्राप्त की। मैंने बिना किसी किस्मत के इसका उपयोग करके PHP में एन्क्रिप्ट करने की कोशिश की। – shanavascet

+2

दोनों प्लेटफार्मों पर चतुर्थ के बाइट मानों की तुलना करें। याद रखें कि सममित सिफर के इनपुट और आउटपुट बाइट्स में हैं, और बाइट्स के क्रम को सिफर के लिए पूर्वनिर्धारित किया गया है। आपको हमेशा प्लेटफॉर्म के अप्रासंगिक परिणाम मिलना चाहिए। तो सुनिश्चित करें कि आपके द्वारा एल्गोरिदम में इनपुट किए गए मान दोनों प्लेटफॉर्म पर समान हैं। ऐसा करने का सबसे अच्छा तरीका क्रिप्टोग्राफिक ऑपरेशन करने से पहले हेक्साडेसिमल में इनपुट मानों को मुद्रित करना है। (चरित्र-) एन्कोडिंग/डिकोडिंग मुद्दों से सावधान रहें! यदि संभव हो, तो समान * बाइट सरणी * का उपयोग करके एल्गोरिदम के इनपुट/आउटपुट का परीक्षण करें। –

+0

बहुत बहुत धन्यवाद उल्लू .. मैंने आपके द्वारा उल्लिखित चरणों का पालन किया .. मेरे प्रश्न का उत्तर देने के लिए और यहां टिप्पणियों के लिए आपके धैर्य के लिए धन्यवाद ... आपको प्यार है। – shanavascet

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