hi 大家好.
我用 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模式加密,后端能够解密的?
迷茫2017-04-10 12:44:13
<?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"> <p> <label for="user">User</label> <input type="text" value="" placeholder="Your login name" name="user"/> </p> <p> <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=""/> </p> <input type="submit" value="Login" id="submit"/> </form> </body> </html>