如何在PHP中不使用mcrypt库加密字符串

5

在PHP中,如果没有mcrypt库,需要使用密钥来加密字符串。

function encrypt($str, $pass){
        $str_arr = str_split($str);
        $pass_arr = str_split($pass);
        $add = 0;
        $div = strlen($str) / strlen($pass);
        while ($add <= $div) {
             $newpass .= $pass;
             $add++;
        }
        $pass_arr = str_split($newpass);
        foreach($str_arr as $key =>$asc) {
            $pass_int = ord($pass_arr[$key]);
            $str_int = ord($asc);
            $int_add = $str_int + $pass_int;
            $ascii .= chr($int_add);
        }
        return $ascii;
    }

    function decrypt($enc, $pass){
        $enc_arr = str_split($enc);
        $pass_arr = str_split($pass);
        $add = 0;
        $div = strlen($enc) / strlen($pass);
        while ($add <= $div) {
            $newpass .= $pass;
            $add++;
        }
        $pass_arr = str_split($newpass);
        foreach($enc_arr as $key =>$asc) {
            $pass_int = ord($pass_arr[$key]);
            $enc_int = ord($asc);
            $str_int = $enc_int - $pass_int;
            $ascii .= chr($str_int);
        }
        return $ascii;
    }

在这个例子中,如果出现了字符“i”,那么它将无法正常工作。我进行了测试。


说啥?需要更多信息来回答这个问题。 - Andy Moore
5个回答

6
这里还有另一种方法:
$key = 'the quick brown fox jumps over the lazy ';
$string = 'Hey we are testing encryption';

echo enc_encrypt($string, $key)."\n";
echo enc_decrypt(enc_encrypt($string, $key), $key)."\n";

function enc_encrypt($string, $key) {
    $result = '';
    for($i = 0; $i < strlen($string); $i++) {
        $char = substr($string, $i, 1);
        $keychar = substr($key, ($i % strlen($key))-1, 1);
        $char = chr(ord($char) + ord($keychar));
        $result .= $char;
    }

    return base64_encode($result);
}

function enc_decrypt($string, $key) {
    $result = '';
    $string = base64_decode($string);

    for($i = 0; $i < strlen($string); $i++) {
        $char = substr($string, $i, 1);
        $keychar = substr($key, ($i % strlen($key))-1, 1);
        $char = chr(ord($char) - ord($keychar));
        $result .= $char;
    }

    return $result;
}

再次提醒,不要期望这个系统非常安全。


在加密函数的开头进行URL编码,然后在解密函数的开头进行URL解码怎么样?否则结果可能包含“+”,“=”和“/”字符。 - trante
我认为更好的方法是,在 enc_decrypt 中添加 **$string=urldecode($string);**,并在 enc_encrypt 中添加 **return urlencode(base64_encode($result));**。 - trante

5
这段代码效率相对较低,我并不惊讶它没有得到预期的结果。
echo RotEncrypt('cheese', 'pie') . "\n<br>\n"
    .RotDecrypt(RotEncrypt('cheese', 'pie'), 'pie');
// ÓÑÊÕÜÊ
// cheese

function RotEncrypt($str, $pass){
   $pass = str_split(str_pad('', strlen($str), $pass, STR_PAD_RIGHT));
   $stra = str_split($str);
   foreach($stra as $k=>$v){
     $tmp = ord($v)+ord($pass[$k]);
     $stra[$k] = chr( $tmp > 255 ?($tmp-256):$tmp);
   }
   return join('', $stra);
}
function RotDecrypt($str, $pass){
   $pass = str_split(str_pad('', strlen($str), $pass, STR_PAD_RIGHT));
   $stra = str_split($str);
   foreach($stra as $k=>$v){
     $tmp = ord($v)-ord($pass[$k]);
     $stra[$k] = chr( $tmp < 0 ?($tmp+256):$tmp);
   }
   return join('', $stra);
}

我测试过,对我来说似乎可以正常工作。

无论如何,我觉得我应该提醒您,这是一种非常不安全的加密形式,大多数密码使用相同的字符集和相对较小的长度范围,这使得这个系统非常容易被人破解,从而准确地获取密码。



1

我在prestashop 1.4.4.1中使用了jlogsdon的enc_encryptenc_decrypt来包装Rijndael类中的encryptdecrypt方法,这些方法使用了mcrypt。我没有检查enc_encryptenc_decrypt是否与mcrypt_encryptmcrypt_decrypt完全相同,但它们似乎在prestashop 1.4.4.1中工作良好。非常感谢。


0
问题虽然旧了,但由于PHP 7没有mcrypt,我遇到了同样的问题。我找到的最佳解决方案是使用OpenSSL。它已经内置在PHP中,您不需要任何外部库。
加密方法如下:
function encrypt($key, $payload) {
  $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
  $encrypted = openssl_encrypt($payload, 'aes-256-cbc', $key, 0, $iv);
  return base64_encode($encrypted . '::' . $iv);
}

解密:

function decrypt($key, $garble) {
    list($encrypted_data, $iv) = explode('::', base64_decode($garble), 2);
    return openssl_decrypt($encrypted_data, 'aes-256-cbc', $key, 0, $iv);
}

参考链接:https://www.shift8web.ca/2017/04/how-to-encrypt-and-execute-your-php-code-with-mcrypt/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接