2014-10-10 76 views
0

在PHP返回不同的值加密算法在PHP和JavaScript

<?php 
    $token = '[email protected]|ts=1412917909|hash=r1xWbgfHUxDLlppGYuOKQJdIM1MTrkryEArkMQx9ERw=|url=http://myintranet.com'; 
    $key = 'a1cbbb6eb5cb2c1c27a9f02a4434d3af'; 
    $token = mb_convert_encoding($token ,'UTF-16LE'); 
    $blockSize = 16; 
    $pad = $blockSize - (strlen($token) % $blockSize); 
    $token .= str_repeat(chr($pad), $pad); 
    $token = mcrypt_encrypt(MCRYPT_RIJNDAEL_128,$key, $token, MCRYPT_MODE_CBC, $iv); 

    $token = base64_encode($token); 
    echo "\n This is the token $token \n"; 
?> 

輸出 - :

This is the token TXz3UEgAdjGhyriNGcMJBUk4QcW3dA7rttzjbKztw19X8bSIMDZt8s6uSQy2OP5QcSpJuReKv73wFXzPyCXt05CNY6XWlx9Lfrv6Nosj0+4mHdD7/Wvx0QWqxuuv5qv4sgtgSif59Wy/ZAoYhfH8yzN/3hWnx6zzOrV6jxyDttmffk1zcBwtJ3X41mMVbPLOd1/2K3ZYxCcJ1VxESFDNB4N1okvGMRkCM0tL77oZiKv+n6CP9FEgKivCfvytFB8JWc9K++8vbLdV/iGgkEa7h0pfAZtYpryQQjFzqLx8NSQ= 

在Javascript中

'use strict'; 

var CryptoJS = require("crypto-js"); 

String.prototype.repeat = function(num) 
{ 
    return new Array(num + 1).join(this); 
} 

function encodeUTF16LE(str) { 
    var out, i, len, c; 
    var char2, char3; 

    out = ""; 
    len = str.length; 
    i = 0; 
    while(i < len) { 
     c = str.charCodeAt(i++); 
     switch(c >> 4) 
     { 
      case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: 
      // 0xxxxxxx 
      out += str.charAt(i-1); 
      break; 
      case 12: case 13: 
      // 110x xxxx 10xx xxxx 
      char2 = str.charCodeAt(i++); 
      out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); 
      out += str.charAt(i-1); 
      break; 
      case 14: 
      // 1110 xxxx 10xx xxxx 10xx xxxx 
      char2 = str.charCodeAt(i++); 
      char3 = str.charCodeAt(i++); 
      out += String.fromCharCode(((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0)); 
      break; 
     } 
    } 

    var byteArray = new Uint8Array(out.length * 2); 
    for (var i = 0; i < out.length; i++) { 
     byteArray[i*2] = out.charCodeAt(i); // & 0xff; 
     byteArray[i*2+1] = out.charCodeAt(i) >> 8; // & 0xff; 
    } 

    return String.fromCharCode.apply(String, byteArray); 
} 

var token = '[email protected]|ts=1412917909|hash=r1xWbgfHUxDLlppGYuOKQJdIM1MTrkryEArkMQx9ERw=|url=http://myintranet.com'; 
var key = 'a1cbbb6eb5cb2c1c27a9f02a4434d3af'; 
var blockSize = 16; 
token = encodeUTF16LE(token); 
var pad = blockSize - (token.length % blockSize); 

token = token + (String.fromCharCode(pad)).repeat(pad); 

token = CryptoJS.AES.encrypt(token, key, 
    { iv: iv, 
     mode: CryptoJS.mode.CBC 
    }); 

console.log("\n This is the token " + token + "\n"); 

token = token.ciphertext.toString(CryptoJS.enc.Base64); 
console.log("\n This is the token " + token + "\n"); 

輸出

This is the token U2FsdGVkX19iQjVHkx/vmhljCsRyTBUA0QFJ8I+pPvxAa2dK6iO4r9FUw2Um2j0H+iyXZ/G0UO0fhJTFzfJEfS1cMfAaq0Z7UBUpVhtrH5IArr2F3BI6yWC8Kpo4ZimyW+xnWp0BYUpLUNQTLsFooiIqPHv3s9HHMe3k0altm6ou1pAKaIr8IAY1OzIDTbaRO55mPf0rU6Z2XTLGR6kYoAx9Lk4dZ3RA66cynXWFMuHznL0fik3phZ8cUiKd/Twquil97YHT+CB/1ulxEBD17VQvnsCJI1lYNn9dyWAUG96KMgGk3jFxiW9eRzV5Poywnt0QNaRpmZiG41KNFmtMtw== 


This is the token GWMKxHJMFQDRAUnwj6k+/EBrZ0rqI7iv0VTDZSbaPQf6LJdn8bRQ7R+ElMXN8kR9LVwx8BqrRntQFSlWG2sfkgCuvYXcEjrJYLwqmjhmKbJb7GdanQFhSktQ1BMuwWiiIio8e/ez0ccx7eTRqW2bqi7WkApoivwgBjU7MgNNtpE7nmY9/StTpnZdMsZHqRigDH0uTh1ndEDrpzKddYUy4fOcvR+KTemFnxxSIp39PCq6KX3tgdP4IH/W6XEQEPXtVC+ewIkjWVg2f13JYBQb3ooyAaTeMXGJb15HNXk+jLCe3RA1pGmZmIbjUo0Wa0y3 

我認爲問題是CryptoJS.AES.encrypt,我沒有通過它正確的配置?

真的停留在這個,所以如果你有任何建議,我想知道。

+0

什麼是'$ key'和'key'? PHP的mcrypt和CryptoJS以不同的方式處理關鍵輸入:https://stackoverflow.com/a/24343162/371137 – Perseids 2014-10-10 12:54:00

+0

@Perseids - 只更新了關鍵值。密鑰由算法生成,但在兩種情況下都至少相同。我使用MCRYPT_RIJNDAEL_128,所以我認爲它可以完成,但我很不確定填充的工作原理。 – 2014-10-10 17:27:10

回答

2

在這兩種情況下,關鍵都沒有按照您的預期處理。 'a1cbbb6eb5cb2c1c27a9f02a4434d3af'是16字節(= 128位)密鑰的十六進制表示,可用於AES128。

mcrypt不知道它得到一個十六進制表示形式,並將其視爲32字節的字符串,並且 - IIRC - 除了其前16個字節('a1cbbb6eb5cb2c1c')以外的所有內容都拋出。您需要unhexlify密鑰才能獲取原始字節:$key=pack('H*', 'a1cbbb6eb5cb2c1c27a9f02a4434d3af')

CryptoJS也不知道它提供了密鑰的十六進制表示和treats it as password instead, which is used as input to PBKDF2。該庫有它的own unhexlify routinesvar key = CryptoJS.enc.Hex.parse('a1cbbb6eb5cb2c1c27a9f02a4434d3af');生成的WordArray將被CryptoJS視爲二進制密鑰輸入。