【问题标题】:Javascript to PHP - RSA encrypt with modulus and exponentJavascript 到 PHP - RSA 使用模数和指数加密
【发布时间】:2017-11-03 13:43:49
【问题描述】:

我有 javascript https://notepad.pw/codeherejs 中的代码

var c = 'd3bcef1f00424f3261c89323fa8cdfa12bbac400d9fe8bb627e8d27a44bd5d59dce559135d678a8143beb5b8d7056c4e1f89c4e1f152470625b7b41944a97f02da6f605a49a93ec6eb9cbaf2e7ac2b26a354ce69eb265953d2c29e395d6d8c1cdb688978551aa0f7521f290035fad381178da0bea8f9e6adce39020f513133fb';
var f = '10001';
var g = new RSAKey;
    g.setPublic(c, f);
    var result = g.encrypt(password)

它工作正常。给我结果是result = 1e2738d762382f82f8412b87e9dd9a18aaa52ea28f6b204bb0f1e0f710a973aaa417e533d39127fd1d8959c553ae53dd83738e4eb6544cb77fd08438afd33594c42ff7e5186bd23908b642188b82b7552140af82f7bd5d768770cd9305573640739be4a70bbc2bd190c5a192685ab88c5a612680005eff2f37944c8e24803ea2

我将代码转换为 PHP,我使用 phpseclib

$fm_modulus = 'd3bcef1f00424f3261c89323fa8cdfa12bbac400d9fe8bb627e8d27a44bd5d59dce559135d678a8143beb5b8d7056c4e1f89c4e1f152470625b7b41944a97f02da6f605a49a93ec6eb9cbaf2e7ac2b26a354ce69eb265953d2c29e395d6d8c1cdb688978551aa0f7521f290035fad381178da0bea8f9e6adce39020f513133fb';

$fm_exponent = '10001';

$rsa = new Crypt_RSA();
$modulus = new Math_BigInteger(base64_decode($fm_modulus), 256);
$exponent = new Math_BigInteger(base64_decode($fm_exponent), 256);

$rsa->loadKey(array('n' => $modulus, 'e' => $exponent));
$pass_ok = $rsa->encrypt($pass);

PHP 为我返回符号,我不知道如何将其转换为纯文本(在 javascript 中的结果相同)。我尝试base64,哈希sha256 sha512。都是假的,请帮帮我

【问题讨论】:

  • 加密返回字节数组。 JS 显示的是字节数组的十六进制表示。显然 PHP 直接将其转换为字符串。所以你应该使用一些通用的 - Base64 应该是好的,尝试将 JS 数组转换为 base64 以查看结果。
  • 我尝试 bin2hex,结果我从 php 得到的结果不一样 Javascript :(
  • 使用安全密码的加密结果应该总是不同的:结果是随机的。您应该通过使用一个运行时加密并使用另一个运行时解密来进行检查。您可以尝试直到世界末日在加密后创建相同的字节数组即使在同一平台上

标签: javascript php encryption rsa phpseclib


【解决方案1】:

$fm_modulus$fm_exponent 不是 base64 编码的,也不是 base-256 编码的。它们是十六进制编码的,就是这样。所以试试这个:

$rsa = new Crypt_RSA();
$modulus = new Math_BigInteger($fm_modulus, 16);
$exponent = new Math_BigInteger($fm_exponent, 16);

我能够通过 $fm_exponent 是 10001 来识别这一点。10001 是 65537 的十六进制编码,这是一个非常常见的 RSA 指数。

我还怀疑 phpseclib 使用的填充模式可能不正确。你可能需要$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_NONE);$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);

实际上有点难以确定,因为您没有发布私钥,因此无法解密结果。您也没有发布您要加密的内容的明文。正如 Maarten Bodewes 所说,使用良好的填充模式,每次尝试加密相同的明文时密文都会有所不同,但您的 JS 库可能没有使用良好的填充模式。默认情况下,phpseclib 使用 OAEP,它确实具有随机输出,但“教科书 RSA”不使用随机填充(或任何填充,真的)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-13
    • 2010-10-31
    • 2017-06-20
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    相关资源
    最近更新 更多