Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/241.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中从密码生成RSA密钥_Php_Encryption_Rsa - Fatal编程技术网

在PHP中从密码生成RSA密钥

在PHP中从密码生成RSA密钥,php,encryption,rsa,Php,Encryption,Rsa,与问题中的问题类似,我希望使用给定的密码重复创建同一对RSA密钥 上述问题的答案如下: from Crypto.Protocol.KDF import PBKDF2 from Crypto.PublicKey import RSA password = "swordfish" # for testing salt = "yourAppName" # replace with random salt if you can store one master_key = PBKDF2(

与问题中的问题类似,我希望使用给定的密码重复创建同一对RSA密钥

上述问题的答案如下:

from Crypto.Protocol.KDF import PBKDF2
from Crypto.PublicKey import RSA

password = "swordfish"   # for testing
salt = "yourAppName"     # replace with random salt if you can store one

master_key = PBKDF2(password, salt, count=10000)  # bigger count = better

def my_rand(n):
    # kluge: use PBKDF2 with count=1 and incrementing salt as deterministic PRNG
    my_rand.counter += 1
    return PBKDF2(master_key, "my_rand:%d" % my_rand.counter, dkLen=n, count=1)

my_rand.counter = 0
RSA_key = RSA.generate(2048, randfunc=my_rand)
我尝试在PHP中复制此代码,如下所示:

$password = "swordfish";
$salt = "yourAppName";

$master_key = hash_pbkdf2("sha256", $password, $salt, 10, 256);

$counter = 0;
function my_rand($n) {
  $counter++;
  return hash_pbkdf2("sha256", $master_key, "my_rand:" . $counter, 10, 256);
}

$RSA_key = openssl_pkey_new(???);
但是我现在不知道如何使用自定义随机函数复制RSA密钥生成器,因为PHP
openssl\u pkey\u new
函数和
phpseclib
都没有添加自定义随机函数的选项


如何从给定密码重复生成相同的RSA密钥对?

TL;DR:您不应该从给定密码生成RSA密钥对


看起来OpenSSL和phpseclib都是在考虑到这一点的情况下创建的。这并不奇怪,因为有很多话要说。此外,还有许多实施问题


如果您仍然继续实现这个不明智的方案,那么您应该查找PHP实现以生成密钥,然后将其与您的解决方案一起存储。原因是,否则随机数生成、素数查找或RSA密钥生成方法可能会在内部发生更改(当您升级库时),并生成不同的密钥对。我不会在Java上使用这个解决方案,即使它允许您插入自己的RNG,以允许生成确定性密钥对,这是您试图做的技术术语

还有其他让用户保持私钥安全的方法,例如基于密码的密钥加密。这需要存储加密密钥,但至少这是一种常见的做法,失败的原因要少得多

如果你想加密任意大小的消息,你需要某种混合加密技术——就像你必须加密任何其他类型的RSA密钥对一样,真的


请注意,椭圆曲线加密的情况稍好一些。您可以将PBKDF2与SHA-256组合以创建私钥,然后通过执行基点G与该私钥值的点乘来派生公钥。这不太可能失败。您可以使用ECIE使用椭圆曲线加密,因为EC没有直接加密消息或密钥的方法


但是,您仍然存在一个问题,即您永远无法更改密码,并且必须使用常量salt来始终生成相同的私钥和公钥。因此,我仍然不推荐该方案,因为它允许离线、多目标攻击使用公钥值或密文查找密码


为了确保找不到密码,密码必须非常强大—强大到您可能必须将其存储在某个位置。

基于密码生成密钥对的目的是什么?是出于学习目的还是出于好奇?我这样问是因为我对这个用例非常感兴趣。我想这样做的目的是因为我想尝试使用RSA制作一个加密的聊天应用程序。此聊天应用程序应允许用户使用用户名+密码登录,因此需要根据用户名+密码生成密钥,但生成密钥的方式应确保用户可以多次登录。但生成密钥对的过程意味着您需要一个以前未使用过的新密钥,这就是生成两个大素数的关键所在。如果将非对称密钥当作共享对称密钥使用,那么它的用途是什么?你所做的是使用一个共享的秘密来计算一个加密密钥——你的想法是好的,但是你的执行是有缺陷的。您遇到的是Diffie-Hellman密钥交换,但您的过程很糟糕。我建议你用谷歌搜索我提到的东西(Diffie Hellman)并重新思考你的过程。重申你所追求的——从用户名和密码中获取加密密钥绝对是错误的方法。如果您正在创建加密聊天应用程序,您应该通过DH(Diffie Hellman)在双方之间协商加密密钥,然后双方创建密钥,而不实际传输密钥。这样,您可以在每次打开参与者之间的新连接时创建新密钥。基于用户名或密码创建一个相同的非对称密钥是不安全的-密钥应该是不可用的,在您的情况下-它们不是。抱歉,Mjh,但这在结构上没有缺陷,即使它确实有大量的和。所以,是的,它不应该被使用,但除了你说的原因。如果实现的话,我会使用椭圆曲线密码,但基本上,这会用一罐含有成分的蠕虫来代替一罐蠕虫。