2012-11-12 80 views
2

我有一個將基於JS的RSA文件轉換爲PHP的問題。將JavaScript RSA函數轉換爲PHP函數

的JavaScript:

主文件:

var RSAPublicKey = function($modulus_hex, $encryptionExponent_hex) { 
    this.modulus = new BigInteger($modulus_hex, 16); 
    this.encryptionExponent = new BigInteger($encryptionExponent_hex, 16); 
} 

var Base64 = { 
base64: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/=", 
encode: function($input) { 
    if (!$input) { 
     return false; 
    } 
    var $output = ""; 
    var $chr1, $chr2, $chr3; 
    var $enc1, $enc2, $enc3, $enc4; 
    var $i = 0; 
    do { 
     $chr1 = $input.charCodeAt($i++); 
     $chr2 = $input.charCodeAt($i++); 
     $chr3 = $input.charCodeAt($i++); 
     $enc1 = $chr1 >> 2; 
     $enc2 = (($chr1 & 3) << 4) | ($chr2 >> 4); 
     $enc3 = (($chr2 & 15) << 2) | ($chr3 >> 6); 
     $enc4 = $chr3 & 63; 
     if (isNaN($chr2)) $enc3 = $enc4 = 64; 
     else if (isNaN($chr3)) $enc4 = 64; 
     $output += this.base64.charAt($enc1) + this.base64.charAt($enc2) + this.base64.charAt($enc3) + this.base64.charAt($enc4); 
    } while ($i < $input.length); 
    return $output; 
}, 
decode: function($input) { 
    if(!$input) return false; 
    $input = $input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 
    var $output = ""; 
    var $enc1, $enc2, $enc3, $enc4; 
    var $i = 0; 
    do { 
     $enc1 = this.base64.indexOf($input.charAt($i++)); 
     $enc2 = this.base64.indexOf($input.charAt($i++)); 
     $enc3 = this.base64.indexOf($input.charAt($i++)); 
     $enc4 = this.base64.indexOf($input.charAt($i++)); 
     $output += String.fromCharCode(($enc1 << 2) | ($enc2 >> 4)); 
     if ($enc3 != 64) $output += String.fromCharCode((($enc2 & 15) << 4) | ($enc3 >> 2)); 
     if ($enc4 != 64) $output += String.fromCharCode((($enc3 & 3) << 6) | $enc4); 
    } while ($i < $input.length); 
    return $output; 
} 
}; 

var Hex = { 
hex: "abcdef", 
encode: function($input) { 
    if(!$input) return false; 
    var $output = ""; 
    var $k; 
    var $i = 0; 
    do { 
     $k = $input.charCodeAt($i++); 
     $output += this.hex.charAt(($k >> 4) &0xf) + this.hex.charAt($k & 0xf); 
    } while ($i < $input.length); 
    return $output; 
}, 
decode: function($input) { 
    if(!$input) return false; 
    $input = $input.replace(/[^0-9abcdef]/g, ""); 
    var $output = ""; 
    var $i = 0; 
    do { 
     $output += String.fromCharCode(((this.hex.indexOf($input.charAt($i++)) << 4) & 0xf0) | (this.hex.indexOf($input.charAt($i++)) & 0xf)); 
    } while ($i < $input.length); 
    return $output; 
} 
}; 

var RSA = { 

getPublicKey: function($modulus_hex, $exponent_hex) { 
    return new RSAPublicKey($modulus_hex, $exponent_hex); 
}, 

encrypt: function($data, $pubkey) { 
    if (!$pubkey) return false; 
    $data = this.pkcs1pad2($data,($pubkey.modulus.bitLength()+7)>>3); 
    if(!$data) return false; 
    $data = $data.modPowInt($pubkey.encryptionExponent, $pubkey.modulus); 
    if(!$data) return false; 
    $data = $data.toString(16); 
    return Base64.encode(Hex.decode($data)); 
}, 

pkcs1pad2: function($data, $keysize) { 
    if($keysize < $data.length + 11) 
     return null; 
    var $buffer = []; 
    var $i = $data.length - 1; 
    while($i >= 0 && $keysize > 0) 
     $buffer[--$keysize] = $data.charCodeAt($i--); 
    $buffer[--$keysize] = 0; 
    while($keysize > 2) 
     $buffer[--$keysize] = Math.floor(Math.random()*254) + 1; 
    $buffer[--$keysize] = 2; 
    $buffer[--$keysize] = 0; 
    return new BigInteger($buffer); 
} 
} 

我如何使用它:

var pubKey = RSA.getPublicKey(results.publickey_mod, results.publickey_exp); 
var encryptedPassword = RSA.encrypt(form.elements['password'].value, pubKey); 

現在我想將其轉換成PHP,爲這事我到目前爲止已經試過:

$pkey = $json["publickey_mod"]; 
$rsa = new Crypt_RSA(); 

$rsa->loadKey($pkey); 
$rsa->exponent = $json["publickey_exp"]; 
echo ($rsa->setPublicKey($pkey))?"success":"fail"; 

$plain = "text"; 
echo $rsa->encrypt($plain); 

但它總是打印一個「失敗」,它有什麼問題?

如何關鍵是這樣的:

CD5D11DFC04D457B864421AA483118EEA3A96C97E01ABFA4BAD356EC3CE6CA7E3F61665BAA1322D1D6C763D4463C1B41D69397281538D22302D8817CC10AEBDA96970DA4BA46BA79808E3B7BC3D38C1C2FD746E73EA5907F07C9588A1AF2C337FED1B7C8BB29304035420FB7EDE92511D1B07A63E21A5C36F132B556EE879113E88395ACCE9B987E478F8EA11B34634BCDA863DE7045EA9D7AB3240F406C572F36FDE1DB1534F92022B91DFBE23F980D0190D69953037EF9F38F98DA1A8028BE009CE82B979E8E427305802330111A78737D8E11C9CB132170CB34618941FA2AC2C754338886BFEE7DAD779036B292F9711DD9C765F37D42B6C0DC0BCCC83765

+0

你試過' - > exponent = pack('H *','CD5D ....');'而不是? –

+0

指數有不同的格式,這是一個Linux時間戳 – user1818486

+0

我的意思是,使用'$ pkey = pack('H *',$ json ['publickey_mod']);' –

回答

2

我知道這有點老大聲,但它看起來像你使用PKCS#1填充。 phpseclib默認使用OAEP填充。嘗試這樣做:

$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);