使用公钥加密在Javascript中加密,在PHP中解密

Tib*_*tan 33 javascript php rsa pgp public-key

我想用JavaScript加密,用PHP解密,使用公钥加密.我一直在努力寻找可以实现这一目标的库,但我遇到了问题.

我目前正在查看openpgpjs,但我需要在所有浏览器中提供支持,甚至测试页面也只在列出的受支持浏览器(Google Chrome)上出现错误.

关于最终目标的说明:

TCP连接已受SSL保护.这一保护层的主要目的是防止有意或无意的网络服务器日志记录,崩溃转储等.

在PHP端,将生成临时私钥(它将在短时间后过期).调用者(在Javascript中)负责在新的公钥到期时要求它.私钥到期的原因是为了防止记录加密数据解密,以防存储私钥的服务器稍后被泄露.

服务器受损的情况:有人获取除数据库服务器之外的所有计算机的备份(并且由于防火墙而无法访问数据库,即使他找到了用户和密码).由于加密记录数据的私钥不再存在,攻击者无法做到.

Ja͢*_*͢ck 33

我在登录页面上使用了类似的东西; 它使用给定的公钥信息(N,e)加密登录凭证,该信息可以在PHP中解密.

它使用以下文件JSBN:

  • jsbn.js - 使用大整数
  • rsa.js - 仅用于RSA加密(使用jsbn.js)
  • rng.js - 基本熵收集器
  • prng4.js - ARC4 RNG后端

要加密数据:

$pk = '-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----';
$kh = openssl_pkey_get_private($pk);
$details = openssl_pkey_get_details($kh);

function to_hex($data)
{
    return strtoupper(bin2hex($data));
}

?>
<script>
var rsa = new RSAKey();
rsa.setPublic('<?php echo to_hex($details['rsa']['n']) ?>', '<?php echo to_hex($details['rsa']['e']) ?>');

// encrypt using RSA
var data = rsa.encrypt('hello world');
</script>
Run Code Online (Sandbox Code Playgroud)

这是您解码发送数据的方式:

$kh = openssl_pkey_get_private($pk);
$details = openssl_pkey_get_details($kh);
// convert data from hexadecimal notation
$data = pack('H*', $data);
if (openssl_private_decrypt($data, $r, $kh)) {
   echo $r;
}
Run Code Online (Sandbox Code Playgroud)


Vla*_*mos 24

检查node-rsa.

它是一个node.js模块

此模块提供对OpenSSL的RSA公钥例程的访问.支持仅限于RSAES-OAEP和使用公钥加密,使用私钥解密.

也许您可以将其移植到浏览器中运行.

UPDATE

用于javascript的RSA客户端库:( pidcrypt已正式停用且网站域已过期 - 请参阅@ jack的答案,其中包含与pidcrypt相同的库). https://www.pidder.com/pidcrypt/?page=rsa

PHP服务器端组件:http: //phpseclib.sourceforge.net/

祝好运!


Sco*_*ski 13

小心实施RSA.实际上,您可能根本不应该使用RSA.(改用libsodium!)

即使你正在使用一个库(例如直接使用PHP的OpenSSL扩展,或者直到最近Zend\Crypt),仍然有很多可能出错的地方.特别是:

  • PKCS1v1.5填充是默认的(在许多情况下是唯一支持的填充模式),容易受到一类称为填充oracle的选择密文攻击.这是Daniel Bleichenbacher首先发现的.1998年.
  • RSA不适用于加密大型消息,因此实现者经常做的是接收长消息,将其分解为固定大小的块,并分别加密每个块.这不仅速度慢,而且类似于对称密钥加密的可怕ECB模式.

与Libsodium一起做的最好的事情

在沿着这条路线前,您可能需要阅读几次JavaScript Cryptography Considered Harmful.但那说......

  1. 将TLSv1.2与HSTS和HPKP一起使用,最好使用ChaCha20-Poly1305和/或AES-GCM以及ECDSA-P256证书(重要的是:当IETF命名为Curve25519和Ed25519时,请转而使用).
  2. libsodium.js添加到您的项目中.
  3. 使用crypto_box_seal()公钥加密您的邮件,客户端.
  4. 在PHP中,使用\Sodium\crypto_box_seal_open()相应的公钥密钥来解密消息.

我需要使用RSA来解决这个问题.

请不要.椭圆曲线加密更快,更简单,并且更容易实现,没有侧通道.大多数图书馆已经为您做了这件事.(Libsodium!)

但我真的想用RSA!

好的,请按照这些建议写信,当你犯错误时(如SaltStack所做的那样)不要让StackOverflow哭泣,这会使你的加密无效.

paragonie/easyrsa是一个旨在提供简单易用的RSA加密的选项(没有补充JavaScript实现,请不要求一个).

  • 通过使用RSA-OAEP和MGF1 + SHA256而不是PKCS1v1.5来避免填充神谕.
  • 它通过巧妙的协议设计避免了ECB模式:

EasyRSA加密协议

  1. EasyRSA为对称密钥加密(通过AES)生成随机128位密钥.
  2. 您的纯文本消息使用defuse/php-encryption进行加密.
  3. 您的AES密钥使用RSA加密,由phpseclib提供,使用正确的模式(如上所述).
  4. 此信息作为简单字符串(带校验和)打包在一起.

但是,实际上,如果您找到公钥加密的有效用例,则需要libsodium.