当前位置: 首页 > 知识库问答 >
问题:

生成正确的 AES-256-CBC 密钥 / 如何存储?

徐杰
2023-03-14

我使用Laravel 5.7,并在不同的服务器上运行两个应用程序。我想通过加密进行通信。所以两端都需要有一定的键。默认的 laravel加密设置为 AES-256-CBC。

所以我想,我需要一个32html" target="_blank">字节的密钥,就像这样:

$ key = bin 2 hex(OpenSSL _ random _ pseudo _ bytes(32,$ c strong));

我得到一个64长的十六进制字符串,我想保存在两端,这样双方都可以在一端加密,另一端解密。

但不知怎的,这把钥匙不被接受。Laravel抛出:唯一支持的密码是具有正确密钥长度的AES-128-CBC和AES-256-CBC

我还尝试将其设置为 16 字节,并使用 32 个字符的密钥。也不起作用。

但是,它确实可以使用 16 个字符的密钥将其设置为 8 位。但这对我来说没有任何意义?

Laravel本身使用类似于这样的键:Bas64: X,其中X=44个字符串。

我在某处读到AES-256-CBC需要64个字符的密钥,其中44个字符应该是base64。我不确定这是否正确,但我很难理解这一点。如何阅读带有base64前缀的密钥?如何把它恢复成一个普通的字符串。

现在我已经解决了这个16个字符的字符串,但似乎并不正确。那么,如何生成有效的AES-256-CBC密钥,以及如何存储它呢?如果需要base64,那是如何工作的?对一个64生成的十六进制密钥进行编码会返回一个88的字符串。

任何帮助都值得赞赏,谢谢。

共有2个答案

宋朝
2023-03-14

Laravel使用Illuminate\Support\Facades\Crypt,这是为端到端加密而设计的。因此,这意味着您可以安全地加密和解密数据库中的数据,但它不是为大众通信加密而设计的。

PHP 7.2与LibSodium紧密结合:使用自己的宅基地加密方法是不可取的。您可以在<code>php中启用扩展。ini</code>配置或通过使用该配置编译PHP。你可以在文档上阅读更多内容。

假设鲍勃想给爱丽丝发一条消息。Bob 和 Alice 都需要密钥对来加密和解密消息或数据。

sodium_crypto_box_keypair();

这些应该存储在数据库中,可以使用相互转换器或后者(如base64*)来完成。每个用户都应持有一个唯一的密钥对,该密钥可以在帐户注册时发出。

您可以通过附加Laravel\App\User.php文件并添加新的可填充的密钥对来实现这一点。对表用户创建新的迁移,附加列密钥对,如下所示:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('key_pair')->unique()->nullable();
    });
}

然后转到您的< code > App \ Http \ Controllers \ Auth \ register controller . PHP 文件并追加< code>create方法。

当您现在想要加密时,可以引用用户密钥对。假设鲍勃:鲍勃的id为1。假设爱丽丝:爱丽丝的id为2。

$bob   = User::find(1);
$alice = User::find(2);

现在,我们可以通过创建一个钠加密盒来加密来自 Bob 的消息并将其发送给 Alice,如下所示:

$kp = sodium_crypto_box_keypair_from_secretkey_and_publickey(
    sodium_crypto_box_secretkey($bob->keypair),
    sodium_crypto_box_publickey($alice->keypair) # Encrypt with Alices Public Key
);

$cbox = sodium_crypto_box(base64_encode('Hello, Alice. This is Bob.'), ($nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES)), $kp);

我们现在可以将IV,或者更好地称为nass,和cyprto框发送给Alice。如果Alice现在想阅读消息,她可以使用她的私钥和Bbs公钥来阅读。

$kp = sodium_crypto_box_keypair_from_secretkey_and_publickey(
    sodium_crypto_box_secretkey($alice->keypair),
    sodium_crypto_box_publickey($bob->keypair) # Decrypt with Bobs public key
);

echo base64_decode(sodium_crypto_box_open($cbox, $nonce, $kp));

我构建了一个容器来实现加密,并使用lib钠更容易地对消息进行签名。我希望这有助于理解加密的概念以及如何使用< code>base64*存储

陈茂
2023-03-14

我无法亲自尝试,但请在此处查看源代码:

/**
 * Create a new encryption key for the given cipher.
 *
 * @param  string  $cipher
 * @return string
 */
public static function generateKey($cipher)
{
    return random_bytes($cipher === 'AES-128-CBC' ? 16 : 32);
}

因此,调用< code>random_bytes()(或其openssl等价物)就是您需要做的全部工作,要么请求16字节(在AES-128-CBC的情况下),要么请求32字节(在AES-256-CBC的情况下)。这是有意义的,因为最终,AES的密钥只不过是一堆随机字节。

可能会使您困惑的是术语< code>string的用法。与< code>string类型的常见用法不同,在这种情况下,它不是一个可打印的字符串,而只是一个16或32字节的集合。

这就是Base64翻译出现的原因。它允许您仅通过ASCII字符表示字节集合。我怀疑您所指的“base64:X,其中X=44个字符串”值存在于某些配置文件中,该文件通常只应包含可读字符。实际上,将32字节转换为Base64格式将产生44个字符。在这种情况下,base64:前缀仅用于指示值以base64格式存储。

一个例子可以说明这一切:

$key = random_bytes(32);
var_dump($key);
var_dump(base64_encode($key));

给予

string(32) "?9???֔e?N??Y?&[??b?4@O|?\?"
string(44) "45U5nvetGyfWlGWOF06N+VnIJlvwx2L3fzRAT3z5XPY="

后者是存储密钥的方便格式。

PS:文档的加密 - 配置部分提到

在使用Laravel的加密程序之前,必须在config/app.php配置文件中设置一个密钥选项。您应该使用php artisan key:generate命令来生成这个密钥

也许这个命令可以完成你自己想做的一切?

 类似资料:
  • 我试图让AES-256 CBC加密在PHP、Ruby(使用SymmetricEncryption)和Javascript(使用CryptoJS)中工作。至于前两个: 但是根据这个答案上面的键/iv只提供128位的安全性。 PHP和Ruby将密钥和IV作为二进制字符串。他们不假设它是十六进制编码的。所以,尽管这个密钥中有256位,但安全性实际上只有128位,因为每个字符在十六进制编码的字符串中只有4

  • 我从Python得到一个加密的base64字符串。 格式是AES 256 CBC,但当我尝试使用Android解密时,它将解密字符串返回为nil。 这里我使用https://github.com/fukata/aes-256-cbc-example

  • 我想将下面的PHP脚本转换为dart,我尝试了很多案例,但没有任何帮助。 我试过以下代码;但在这里抛出一个异常加密程序。解密方法。 演示内容; 初始化aes_密码 $aes_secret='123456ac'; 演示内容; ="dBluiiVaHxhRcWJPaEip9kCGXDwufk3mFp8Xe9ioh9UKu6xL CHUZrKvuf3xI7P1vFpvyJ2Vz2Q3ieLEuRHk7N

  • 如何使用PHP安全地生成适用于AES 256哈希数据的密钥? 我尝试过谷歌搜索,找到了大量关于如何使用PHP使用AES 256加密数据的信息,但是所有这些示例都使用了现有的预生成密钥,而我需要在PHP中生成密钥。

  • 我希望有一个用C编写的程序,可以在没有openssl这样的大型库的帮助下,用AES-CBC对字符串进行编码/解码。 目标: 使用密码短语对字符串进行编码/解码: 因此,应用程序需要接受3个输入参数。。。 输入字符串(待编码)/或已编码字符串(待解码) 用于编码/解码字符串的密码 编码或解码指示器 我对C语言不熟悉(我可以用C#编码)。 我已经找到了https://github.com/kokke/

  • 我做了一个简单的文件加密/解密器。它将模式和要操作的文件作为参数。加密时,它生成随机字符串并使用该字符串加密文件。解密文件时,它会提示用户输入密码,并在解密时使用该密码。 我的问题是,解密时得到的不是明文,而是胡言乱语,尽管我小心翼翼地将相同的密钥写入输入。 非常感谢James K Polk提供的加密/解密代码!