开发者社区> 问答> 正文

JAVASCRIPT 客户端加密 PHP服务端解密

我用 crypto-js 在客户端加密:

function encrypt(str) {

var key = $.cookie('key');
var encrypted = CryptoJS.TripleDES.encrypt(str, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.ZeroPadding});
return encrypted;

}
服务端:

$decrypt = mcrypt_decrypt (MCRYPT_3DES, $_SESSION['key'], $encrypted_str_from_client, MCRYPT_MODE_ECB);

print ($decrypt);
这样子无法解密.

请问大家有没有办法做到在客户端 用3DES ECB模式加密,后端能够解密的?

展开
收起
a123456678 2016-03-10 18:26:53 2954 0
1 条回答
写回答
取消 提交回答
  • <?php
    session_start();
    /** PBKDF2 Implementation (as described in RFC 2898);
     *
     *  @param string p password
     *  @param string s salt
     *  @param int c iteration count (use 1000 or higher)
     *  @param int kl derived key length
     *  @param string a hash algorithm
     *
     *  @return string derived key
     */
    function pbkdf2_helper_for_javascript( $p, $s, $c, $kl, $a = 'sha256' ) {
        $hl = strlen( hash( $a, null, true ) );
        $kb = ceil( $kl / $hl );
        $dk = '';
        for ( $block = 1; $block <= $kb; $block++ ) {
            $ib = $b = hash_hmac( $a, $s . pack( 'N', $block ), $p, true );
            for ( $i = 1; $i < $c; $i++ ) {
                $ib ^= ( $b = hash_hmac( $a, $b, $p, true ) );
            }
            $dk .= $ib;
        }
        return substr( $dk, 0, $kl );
    }
    
    function dectypt_from_javascript_encrypt($dectypted_str, $callback = null) {
        $salt = $_SESSION['password_salt'];
        $secret_key = $_SESSION['password_secret'];
        //get the cipher key
        $key = pbkdf2_helper_for_javascript( $secret_key, $salt, 1000, 32 );
    
        //get the IV
        $iv64 = $_REQUEST['iv'];
        $iv = base64_decode($iv64);
    
        //get the HMAC
        $hmac = $_REQUEST['hmac'];
        
        # initialise mcrypt. NB Rijndael-128 covers all variants of AES
        $td = mcrypt_module_open( MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_NOFB, '' );
        
        # do encryption
        $input = base64_decode($dectypted_str);
        mcrypt_generic_init($td, $key, $iv);
        $plain = mdecrypt_generic($td, $input);
        mcrypt_generic_deinit($td);
        
        # shutdown mcrypt
        mcrypt_module_close($td);
    
        # create HMAC for message
        $hmacActual = hash_hmac('sha256', $plain, $iv);
        if($hmac == $hmacActual) {
            if ($callback && is_callable($callback)) {
                $callback('success', $plain);
            }
        } else {
            //解密失败,提示提醒用户
            $callback('error', null);
        }
    
        //session 用完后清除
        $_SESSION['password_secret'] = null;
    }
    
    if ($user = @$_POST['user'] && $password = @$_POST['password']) {
          dectypt_from_javascript_encrypt($_POST['password'], function ($status, $password) {
              print $password;
          });
    }
    
    // 每次发生请求,生成一次key用来解密.
    $key = uniqid();
    //发送到客户端cookie
    setcookie("password_secret", $key, 0);
    setcookie("password_salt", "tuding_salt");
    //并且保存到session用来后续的解密
    $_SESSION['password_secret'] = $key;
    $_SESSION['password_salt'] = 'tuding_salt';
    
    ?>
    
    
    <!DOCTYPE HTML>
    <html lang="en">
        <head>
            <meta charset="utf-8"/>
            <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
            <script type='text/javascript' src="http://crypto-js.googlecode.com/files/2.5.3-crypto.js"></script>
            <script type='text/javascript' src="http://crypto-js.googlecode.com/files/2.5.3-sha256.js"></script>
            <script type='text/javascript' src="http://crypto-js.googlecode.com/files/2.3.0-hmac.js"></script>
            <script type='text/javascript' src="http://crypto-js.googlecode.com/files/2.3.0-pbkdf2.js"></script>
            <script type='text/javascript' src="http://crypto-js.googlecode.com/files/2.3.0-aes.js"></script>
            <script type='text/javascript' src="http://crypto-js.googlecode.com/files/2.5.3-blockmodes.js"></script>
            <script type="text/javascript">
                function doEncrypt(message) {
                    var secret = $.cookie('password_secret');
                    var salt = $.cookie('password_salt');
                    var bytes_iv = Crypto.util.randomBytes(16);
                    var base64_iv = Crypto.util.bytesToBase64(bytes_iv);
                    var hmac = Crypto.HMAC(Crypto.SHA256, message, bytes_iv);
                    var key = Crypto.PBKDF2(secret, salt, 32, {hasher:Crypto.SHA256, iterations:1000, asBytes:true});
                    var cipher =Crypto.AES.encrypt(message, key, {iv:bytes_iv, mode:new Crypto.mode.OFB, asBytes:false});
                    return {iv: base64_iv, hmac: hmac, cipher: cipher};
                }
                $(document).ready(function () {
                    $('#submit').click(function () {
                        var user = $('input[name="user"]').val();
                        var pwd = $('input[name="password"]').val();
                        try {
                            var encrypt_pwd = doEncrypt(pwd);
                            $('input[name="hmac"]').val(encrypt_pwd['hmac']);
                            $('input[name="password"]').val(encrypt_pwd['cipher']);
                            $('input[name="iv"]').val(encrypt_pwd['iv']);
                        }
                        catch (exception) {
                            //TODO:
                        }
                    });
    
                });
            </script>
        </head>
        <body>
            <form action="/index_bk.php" name="login" method="post">
                <div>
                    <label for="user">User</label>
                    <input type="text" value="" placeholder="Your login name" name="user"/>
                </div>
                <div>
                    <label for="password">Password</label>
                    <input type="password" placeholder="your password" name="password" />
                    <input type="hidden" name="hmac" value=""/>
                    <input type="hidden" name="iv" value=""/>
                </div>
                <input type="submit" value="Login" id="submit"/>
            </form>
        </body>
    </html>
    2019-07-17 18:58:08
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
\"视频服务特色解决方案——直播连麦与点播加密 \" 立即下载
编程语言如何演化—— 以 JS 的 private 为例 立即下载
量子加密通信技术 立即下载