如何使用PHP和Redis存储秘密

166 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第21天,点击查看活动详情

构建一个可以在任何支付网络上运行的应用程序的挑战之一是保证用户机密的安全。通常,实现这一点的最佳方法是用户将这些秘密存储在自己的设备(移动应用程序、硬件钱包等)中,但也可能在某些情况下,我们希望将它们集中起来。

在这篇文章中,我试图分享一种非常简单的方法来存储它们,而不使用任何外部系统(如云密钥管理)。这种方法可以在不需要强大安全特性的开发环境中提供帮助,但在具有强大安全后端的 生产环境中也是有效的。

简介

本文假设您了解PHP、composer和redis。

开始

假设你有一个安装了composer的php环境,首先要做的是为php安装Stellar SDK:

composer require soneso/stellar-php-sdk

生成加密密钥来加密我们的秘密

接下来我们需要生成加密密钥来加密我们的秘密。为了做到这一点,我们将使用php钠库。php 7.2版本中附带了这个库。对于旧版本,您可以使用pecl安装它。假设我们使用的是php≥7.2,让我们开始创建加密密钥

$decryptionKey = sodium_crypto_box_keypair();  
$encryptionKey = sodium_crypto_box_publickey($decryptionKey);

现在我们已经创建了加密密钥,我们必须将它们存储在我们的Redis后端。我们有几个选项来与redis与PHP交互。其中之一是predis库。使用composer安装它非常容易

composer require predis/predis

在安装了predis之后,我们可以将加密密钥存储在redis上

$client = new Predis\Client();  
$client->set('stellar:dec', $decryptionKey);  
$client->set('stellar:enc', $encryptionKey);

通过这段简单的代码,我们已经在redis中存储了加密密钥,每当我们想要编码/解码一个秘密时,我们都可以获得它们。所以,下一步是编码一个秘密,并将其存储在redis上。

编码秘密并储存起来

为了创建秘密,我们可以使用类Soneso\StellarSDK\Crypto\KeyPair,因为我们在本文开头安装了Soneso库。从这对密钥中我们可以得到秘密。然后我们将使用我们的加密密钥(已经存储在redis上)来编码秘密。最后,我们将秘密存储在redis。

$client = new Predis\Client();
$keyPair = KeyPair::random();
$secret  = $keyPair->getSecretSeed();
$keySecretName = 'mykeysecretname'; // to identify it on redis
$encryptionKey = $client->get('stellar:enc');

$encodedSecret = sodium_crypto_box_seal($secret, $encryptionKey);
$client->set($keySecretName, $encodedSecret);

现在我们有我们的秘密编码和存储在redis。最后一步将从redis检索它并解码它。

从redis中获取秘密并解码

为了检索和解码秘密,我们必须得到我们的解密密钥(已经存储在redis上)。然后我们必须从redis中获得我们的秘密,最后使用我们的解密密钥来解码它。

$client = new Predis\Client();  
$keySecretName = 'mykeysecretname'; // to identify it on redis  
$decryptionKey = $client->get('stellar:dec');  
$encodedSecret = $client->get($keySecretName);  
  
$decodedSecret = sodium_crypto_box_seal_open($encodedSecret, $decryptionKey);

这就是全部,我们已经检索和解码了我们的秘密,我们可以用它来签署我们的交易。

结论

我写这篇文章的目的是展示一种非常简单的方法,在redis上存储编码的秘密,并能够获得它们。我相信有很多更好的方法来实现它,但我认为它会有所帮助。