php Mcrypt से OpenSSL तक मेरी एन्क्रिप्शन लाइब्रेरी को अपग्रेड करना



encryption (1)

आपके डिक्रिप्शन रूटीन के लिए यह कोड मेरे लिए काम करता है:

public function decrypt($data, $key) {
    $salt = substr($data, 0, 128);
    $enc = substr($data, 128, -64);
    $mac = substr($data, -64);

    list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

    if ($mac !== hash_hmac('sha512', $enc, $macKey, true)) {
         return false;
    }

    $dec = openssl_decrypt($enc, $this->cipher, $cipherKey, OPENSSL_RAW_DATA, $iv);

    return $dec;
}

परीक्षा:

$keys = [
    'this is a secret key.',
    'G906m70p(IhzA5T&5x7(w0%a631)u)%D6E79cIYJQ!iP2U(xT13q6)tJ6gZ3D2wi&0")7cP5',
    chr(6) . chr(200) . chr(16) . 'my key ' . chr(3) . chr(4) . chr(192) . chr(254) . ' zyx0987!!',
    'and finally one more key to test with here:',
];


$data = [
    'A',
    'This is a test',
    'now test encrypting something a little bit longer with 1234567890.',
    '$length = mcrypt_get_block_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC); $last = ord($data[strlen($data) - 1]);',
    'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sit amet pharetra urna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut fringilla, quam sed eleifend eleifend, justo turpis consectetur tellus, quis tristique eros erat at nibh. Nunc dictum neque vel diam molestie fermentum. Pellentesque dignissim dui quis tortor eleifend, ut maximus elit egestas. Donec posuere odio et auctor porta. Quisque placerat condimentum maximus. Curabitur luctus dolor eget sem luctus, in dignissim tortor venenatis. Mauris eget nulla nisl.',
];

$failures = 0;

foreach ($data as $datum) {
    foreach ($keys as $key) {
        $enc = new Encryption(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);

        $encrypted = $enc->encrypt($datum, $key);

        $dec = new EncryptionOpenSsl('bf-cbc');

        $decrypted = $dec->decrypt($encrypted, $key);

        if (strcmp($datum, $decrypted) !== 0) {
            echo "Encryption with key '$key' of '$datum' failed.  '$decrypted' != '$datum'<br><br>\n\n";
            $failures++;
        }
    }
}

if ($failures) {
    echo "$failures tests failed.<br>\n";
} else {
    echo "ALL OKAY<br>\n";
}

यदि आप पुष्टि कर सकते हैं कि यह आपके लिए काम करता है और साथ ही मैं उत्तर को ठीक कर सकता हूं और अंतिम कार्य कोड जोड़ सकता हूं।

मैं एन्क्रिप्शन के लिए नीचे आमतौर पर संदर्भित पुस्तकालय का उपयोग कर रहा हूं। मैं इसे मैक्रिप्ट से ओपनएसएसएल में अपग्रेड करना चाहता हूं, ताकि अब मैं एक पदावनत पुस्तकालय का उपयोग न कर सकूं।

मैं यह पता लगाने की कोशिश कर रहा हूं कि क्या यह संभव है। मैंने इस पर कुछ शोध किया है, लेकिन मुझे परस्पर विरोधी जानकारी मिली है:

इस पोस्ट में कहा गया है कि ओपनएसएसएल का उपयोग करके डेटा को डिक्रिप्ट करना असंभव है जो कि मैक्रोट के साथ एन्क्रिप्ट किया गया था। https://stackoverflow.com/a/19748494/5834657

हालांकि, इस पोस्ट का कहना है कि यह पैडिंग का उपयोग करना संभव है। ऐसा प्रतीत होता है कि मेरा फ़ंक्शन पैडिंग का उपयोग करता है। क्या इस कार्य को करने के लिए सही प्रकार की पैडिंग की आवश्यकता है? https://stackoverflow.com/a/31614770/5834657

<?php 

namespace Utilities\Encryption;

/**
* A class to handle secure encryption and decryption of arbitrary data
*
* Note that this is not just straight encryption.  It also has a few other
* features in it to make the encrypted data far more secure.  Note that any
* other implementations used to decrypt data will have to do the same exact
*  operations.  
*
* Security Benefits:
*
* - Uses Key stretching
* - Hides the Initialization Vector
* - Does HMAC verification of source data
*
*/

class Encryption {

/**
 * @var string $cipher The mcrypt cipher to use for this instance
 */
protected $cipher = '';

/**
 * @var int $mode The mcrypt cipher mode to use
 */
protected $mode = '';

/**
 * @var int $rounds The number of rounds to feed into PBKDF2 for key generation
 */
protected $rounds = 100;

/**
 * Constructor!
 *
 * @param string $cipher The MCRYPT_* cypher to use for this instance
 * @param int    $mode   The MCRYPT_MODE_* mode to use for this instance
 * @param int    $rounds The number of PBKDF2 rounds to do on the key
 */
public function __construct($cipher, $mode, $rounds = 100) {
    $this->cipher = $cipher;
    $this->mode = $mode;
    $this->rounds = (int) $rounds;
}

/**
 * Decrypt the data with the provided key
 *
 * @param string $data The encrypted datat to decrypt
 * @param string $key  The key to use for decryption
 * 
 * @returns string|false The returned string if decryption is successful
 *                           false if it is not
 */
public function decrypt($data, $key) {
    $salt = substr($data, 0, 128);
    $enc = substr($data, 128, -64);
    $mac = substr($data, -64);

    list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

    if ($mac !== hash_hmac('sha512', $enc, $macKey, true)) {
         return false;
    }

    $dec = mcrypt_decrypt($this->cipher, $cipherKey, $enc, $this->mode, $iv);

    $data = $this->unpad($dec);

    return $data;
}

/**
 * Encrypt the supplied data using the supplied key
 * 
 * @param string $data The data to encrypt
 * @param string $key  The key to encrypt with
 *
 * @returns string The encrypted data
 */
public function encrypt($data, $key) {
    $salt = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
    list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

    $data = $this->pad($data);

    $enc = mcrypt_encrypt($this->cipher, $cipherKey, $data, $this->mode, $iv);

    $mac = hash_hmac('sha512', $enc, $macKey, true);
    return $salt . $enc . $mac;
}

/**
 * Generates a set of keys given a random salt and a master key
 *
 * @param string $salt A random string to change the keys each encryption
 * @param string $key  The supplied key to encrypt with
 *
 * @returns array An array of keys (a cipher key, a mac key, and a IV)
 */
protected function getKeys($salt, $key) {
    $ivSize = mcrypt_get_iv_size($this->cipher, $this->mode);
    $keySize = mcrypt_get_key_size($this->cipher, $this->mode);
    $length = 2 * $keySize + $ivSize;

    $key = $this->pbkdf2('sha512', $key, $salt, $this->rounds, $length);

    $cipherKey = substr($key, 0, $keySize);
    $macKey = substr($key, $keySize, $keySize);
    $iv = substr($key, 2 * $keySize);
    return array($cipherKey, $macKey, $iv);
}

/**
 * Stretch the key using the PBKDF2 algorithm
 *
 * @see http://en.wikipedia.org/wiki/PBKDF2
 *
 * @param string $algo   The algorithm to use
 * @param string $key    The key to stretch
 * @param string $salt   A random salt
 * @param int    $rounds The number of rounds to derive
 * @param int    $length The length of the output key
 *
 * @returns string The derived key.
 */
protected function pbkdf2($algo, $key, $salt, $rounds, $length) {
    $size   = strlen(hash($algo, '', true));
    $len    = ceil($length / $size);
    $result = '';
    for ($i = 1; $i <= $len; $i++) {
        $tmp = hash_hmac($algo, $salt . pack('N', $i), $key, true);
        $res = $tmp;
        for ($j = 1; $j < $rounds; $j++) {
             $tmp  = hash_hmac($algo, $tmp, $key, true);
             $res ^= $tmp;
        }
        $result .= $res;
    }
    return substr($result, 0, $length);
}

protected function pad($data) {
    $length = mcrypt_get_block_size($this->cipher, $this->mode);
    $padAmount = $length - strlen($data) % $length;
    if ($padAmount == 0) {
        $padAmount = $length;
    }
    return $data . str_repeat(chr($padAmount), $padAmount);
}

protected function unpad($data) {
    $length = mcrypt_get_block_size($this->cipher, $this->mode);
    $last = ord($data[strlen($data) - 1]);
    if ($last > $length) return false;
    if (substr($data, -1 * $last) !== str_repeat(chr($last), $last)) {
        return false;
    }
    return substr($data, 0, -1 * $last);
 }
}

अपडेट: मैं लाइब्रेरी को ओपनएसएसएल में परिवर्तित करके ओपनएसएसएल का उपयोग करके मैकक्रिप्ट के साथ एन्क्रिप्ट किए गए स्ट्रिंग को डिक्रिप्ट करने की कोशिश कर रहा हूं।

फिर, मैं उपरोक्त कोड का उपयोग करके एक कुंजी को एन्क्रिप्ट कर रहा हूं, और नीचे दिए गए कोड और उसी कुंजी का उपयोग करके उस मूल्य को डिक्रिप्ट करने की कोशिश कर रहा हूं। हालाँकि मुझे बस एक खाली प्रतिक्रिया मिल रही है। अगर मैं टिप्पणी करता हूं:

$ डेटा = $ यह-> अनपैड ($ डेसी)

डिक्रिप्ट फ़ंक्शन में मुझे एक स्ट्रिंग मिलती है, लेकिन यह सिर्फ पात्रों तक उछल जाती है (बहुत कुछ ऐसा लगता है जब यह पहली बार एन्क्रिप्ट किया गया हो।)

<?php 

namespace Utilities\Encryption;

/**
* A class to handle secure encryption and decryption of arbitrary data
*
* Note that this is not just straight encryption.  It also has a few other
*  features in it to make the encrypted data far more secure.  Note that any
*  other implementations used to decrypt data will have to do the same exact
*  operations.  
*
* Security Benefits:
*
* - Uses Key stretching
* - Hides the Initialization Vector
* - Does HMAC verification of source data
*
*/
class EncryptionOpenSsl {

/**
 * @var string $cipher The mcrypt cipher to use for this instance
 */
protected $cipher = '';

/**
 * @var int $mode The mcrypt cipher mode to use
 */
protected $mode = '';

/**
 * @var int $rounds The number of rounds to feed into PBKDF2 for key generation
 */
protected $rounds = 100;

/**
 * Constructor!
 *
 * @param string $cipher The MCRYPT_* cypher to use for this instance
 * @param int    $mode   The MCRYPT_MODE_* mode to use for this instance
 * @param int    $rounds The number of PBKDF2 rounds to do on the key
 */
public function __construct($cipher, $rounds = 100) {
    $this->cipher = $cipher;
    // $this->mode = MCRYPT_MODE_CBC;
    $this->rounds = (int) $rounds;
}

/**
 * Decrypt the data with the provided key
 *
 * @param string $data The encrypted datat to decrypt
 * @param string $key  The key to use for decryption
 * 
 * @returns string|false The returned string if decryption is successful
 *                           false if it is not
 */
public function decrypt($data, $key) {
    $salt = substr($data, 0, 128);
    $enc = substr($data, 128, -64);
    $mac = substr($data, -64);

    list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

    if ($mac !== hash_hmac('sha512', $enc, $macKey, true)) {
         return false;
    }
    $dec = openssl_decrypt($enc, $this->cipher, $key, OPENSSL_RAW_DATA, $iv);
    // $dec = mcrypt_decrypt($this->cipher, $cipherKey, $enc, $this->mode, $iv);

    $data = $this->unpad($dec);

    return $data;
}

/**
 * Encrypt the supplied data using the supplied key
 * 
 * @param string $data The data to encrypt
 * @param string $key  The key to encrypt with
 *
 * @returns string The encrypted data
 */
public function encrypt($data, $key) {
    $salt = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
    list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

    $data = $this->pad($data);

    $enc = mcrypt_encrypt($this->cipher, $cipherKey, $data, $this->mode, $iv);

    $mac = hash_hmac('sha512', $enc, $macKey, true);
    return $salt . $enc . $mac;
}

/**
 * Generates a set of keys given a random salt and a master key
 *
 * @param string $salt A random string to change the keys each encryption
 * @param string $key  The supplied key to encrypt with
 *
 * @returns array An array of keys (a cipher key, a mac key, and a IV)
 */
protected function getKeys($salt, $key) {
    $ivSize = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
    $keySize = mcrypt_get_key_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
    $length = 2 * $keySize + $ivSize;

    $key = $this->pbkdf2('sha512', $key, $salt, $this->rounds, $length);

    $cipherKey = substr($key, 0, $keySize);
    $macKey = substr($key, $keySize, $keySize);
    $iv = substr($key, 2 * $keySize);
    return array($cipherKey, $macKey, $iv);
}

/**
 * Stretch the key using the PBKDF2 algorithm
 *
 * @see http://en.wikipedia.org/wiki/PBKDF2
 *
 * @param string $algo   The algorithm to use
 * @param string $key    The key to stretch
 * @param string $salt   A random salt
 * @param int    $rounds The number of rounds to derive
 * @param int    $length The length of the output key
 *
 * @returns string The derived key.
 */
protected function pbkdf2($algo, $key, $salt, $rounds, $length) {
    $size   = strlen(hash($algo, '', true));
    $len    = ceil($length / $size);
    $result = '';
    for ($i = 1; $i <= $len; $i++) {
        $tmp = hash_hmac($algo, $salt . pack('N', $i), $key, true);
        $res = $tmp;
        for ($j = 1; $j < $rounds; $j++) {
             $tmp  = hash_hmac($algo, $tmp, $key, true);
             $res ^= $tmp;
        }
        $result .= $res;
    }
    return substr($result, 0, $length);
}

protected function pad($data) {
    $length = mcrypt_get_block_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
    $padAmount = $length - strlen($data) % $length;
    if ($padAmount == 0) {
        $padAmount = $length;
    }
    return $data . str_repeat(chr($padAmount), $padAmount);
}

protected function unpad($data) {
    $length = mcrypt_get_block_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
    $last = ord($data[strlen($data) - 1]);
    if ($last > $length) return false;
    if (substr($data, -1 * $last) !== str_repeat(chr($last), $last)) {
        return false;
    }
    return substr($data, 0, -1 * $last);
 }
}




mcrypt