Я пытался понять, как пользоваться Системой управления ключами Google Cloud, и изучил краткие руководства и документацию. Я создал свои брелоки для ключей и их отдельные ключи и протестировал их с помощью SDK на моем ноутбуке, и они отлично работают.
Затем я попытался проработать пример Envelope Encryption, как показано на https://deliciousbrains.com/php-encryption-methods/ используя мою среду разработки WAMP на моем ноутбуке. Я настроил учетную запись службы и переменную среды, как описано в https://cloud.google.com/docs/authentication/production#auth-cloud-implicit-php.
Однако, когда я пытаюсь запустить код в своем браузере, я получаю следующее сообщение:
Fatal error: Uncaught Google_Service_Exception: { "error": { "code": 401, "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "errors": [ { "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "domain": "global", "reason": "unauthorized" } ], "status": "UNAUTHENTICATED" } } in C:\Bitnami\wampstack-7.2.11-0\apache2\htdocs\racingaway\vendor\google\apiclient\src\Google\Http\REST.php:118 Stack trace: #0 C:\Bitnami\wampstack-7.2.11-0\apache2\htdocs\racingaway\vendor\google\apiclient\src\Google\Http\REST.php(94): Google_Http_REST::decodeHttpResponse(Object(GuzzleHttp\Psr7\Response), Object(GuzzleHttp\Psr7\Request), 'Goo in C:\Bitnami\wampstack-7.2.11-0\apache2\htdocs\racingaway\vendor\google\apiclient\src\Google\Http\REST.php on line 118
Я попытался перейти по ссылке в сообщении выше (https://developers.google.com/identity/sign-in/web/devconsole-project), это приводит меня к https://developers.google.com/identity/sign-in/web/sign-in#before_you_begin, который, кажется, о настройке клиента OAuth для конечного пользователя. Тем не менее, то, что я хочу сделать, это проверка подлинности между серверами. Теперь я немного сбит с толку и был бы очень признателен за мудрый совет относительно того, что мне нужно сделать, чтобы заставить мое тестовое приложение работать.
Код, который я использовал ниже:
<?php
use Google_Service_CloudKMS as Kms;
use Google_Service_CloudKMS_DecryptRequest as DecryptRequest;
use Google_Service_CloudKMS_EncryptRequest as EncryptRequest;
class KeyManager
{
private $kms;
private $encryptRequest;
private $decryptRequest;
private $projectId;
private $locationId;
private $keyRingId;
private $cryptoKeyId;
public function __construct(Kms $kms, EncryptRequest $encryptRequest, DecryptRequest $decryptRequest, $projectId, $locationId, $keyRingId, $cryptoKeyId)
{
$this->kms = $kms;
$this->encryptRequest = $encryptRequest;
$this->decryptRequest = $decryptRequest;
$this->projectId = $projectId;
$this->locationId = $locationId;
$this->keyRingId = $keyRingId;
$this->cryptoKeyId = $cryptoKeyId;
}
public function encrypt($data)
{
$key = random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = sodium_crypto_secretbox($data, $nonce, $key);
return [
'data' => base64_encode($nonce . $ciphertext),
'secret' => $this->encryptKey($key),
];
}
public function decrypt($secret, $data)
{
$decoded = base64_decode($data);
$key = $this->decryptSecret($secret);
$nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
$ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
return sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
}
private function encryptKey($key)
{
$this->encryptRequest->setPlaintext(base64_encode($key));
$response = $this->kms->projects_locations_keyRings_cryptoKeys->encrypt(
$this->getResourceName(),
$this->encryptRequest
);
return $response['ciphertext'];
}
private function decryptSecret($secret)
{
$this->decryptRequest->setCiphertext($secret);
$response = $this->kms->projects_locations_keyRings_cryptoKeys->decrypt(
$this->getResourceName(),
$this->decryptRequest
);
return base64_decode($response['plaintext']);
}
public function getResourceName()
{
return sprintf(
'projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s',
$this->projectId,
$this->locationId,
$this->keyRingId,
$this->cryptoKeyId
);
}
}
Вышеупомянутый класс используется кодом ниже:
<?php
require_once( "get_paths.php" );
require_once( GetIncludePath()."class.keymanager.php" );
use Google_Service_CloudKMS as Kms;
use Google_Service_CloudKMS_DecryptRequest as DecryptRequest;
use Google_Service_CloudKMS_EncryptRequest as EncryptRequest;
$client = new Google_Client();
$client->setAuthConfig(getenv('GOOGLE_APPLICATION_CREDENTIALS'));
$client->addScope('https://www.googleapis.com/auth/cloud-platform');
$keyManager = new KeyManager(
new Kms($client),
new EncryptRequest(),
new DecryptRequest(),
// $projectId,
"snappy-thought-226213",
// $locationId,
"europe-west2",
// $keyRingId,
"racingaway_key_ring",
// $cryptoKeyId
"racingaway_key_2");
$encrypted = $keyManager->encrypt('This is a secret!');
var_dump($encrypted);
?>
Задача ещё не решена.
Других решений пока нет …