Быстрая натриевая расшифровка с использованием закрытого ключа

Я использую Swift Sodium на стороне клиента, так как мой сервер использует libsodium для шифрования данных перед тем, как делиться ими со мной через API.

Теперь у меня есть существующий закрытый ключ и открытый ключ в формате String. Я хочу теперь расшифровать зашифрованные данные на моем конце на iOS с помощью Swift.

Как создать пару натриевых ключей, используя открытый и закрытый ключи, которые у меня есть?

Также в идеале я должен использовать только закрытый ключ для расшифровки данных. Итак, как мне это сделать, используя только закрытый ключ в качестве String.

Мой код для расшифровки показан ниже -

func decryptData(dataString: String) -> String? {
    let sodium = Sodium()
    let privateKey = sodium?.utils.hex2bin("MY_SECRET_KEY")

    let publicKey = sodium?.utils.hex2bin("MY_PUBLIC_KEY")

    let message = dataString.data(using: .utf8)!

    if let decrypted = sodium?.box.open(anonymousCipherText: message, recipientPublicKey: publicKey!, recipientSecretKey: privateKey!){
        // authenticator is valid, decrypted contains the original message
        return String(data: decrypted, encoding: String.Encoding.utf8) as String!
    }
    return nil
}

В приведенном выше коде моя расшифрованная строка всегда пуста.

Сервер шифрует данные, используя следующую функцию:

protected function crypt($response)
{
   $message = new HiddenString($response);

   $repository = \App::make(EncryptionKeysRepository::class);
   $enc = $repository->findOneBy(['device' => 'android']);
   $dir = $enc->getDevice();
   $publicKey = $enc->getPublicKey();
   $storage = storage_path();

   if(!file_exists($storage."/{$dir}/")) {
       mkdir($storage."/{$dir}/");
   }

   // save key pair to key store
   $pubFilename = \tempnam($storage."/{$dir}/", 'pub_key');
   file_put_contents($pubFilename, $publicKey);

   $public = KeyFactory::loadEncryptionPublicKey($pubFilename);
   unlink($pubFilename);
   rmdir($storage."/{$dir}/");
   $message = Crypto::seal($message, $public);

   return $message;
}

Расшифровка логики на сервере

protected function deCrypt($response)
{
   $repository = \App::make(EncryptionKeysRepository::class);
   $enc = $repository->findOneBy(['device' => 'android']);
   $dir = $enc->getDevice();
   $publicKey = $enc->getSecretKey();
   $storage = storage_path();

   if(!file_exists($storage."/{$dir}/")) {
       mkdir($storage."/{$dir}/");
   }

   // save key pair to key store
   $secFilename = \tempnam($storage."/{$dir}/", 'sec_key');
   file_put_contents($secFilename, $publicKey);

   $secret = KeyFactory::loadEncryptionSecretKey($secFilename);
   unlink($secFilename);
   rmdir($storage."/{$dir}/");
   $res = Crypto::unseal($response, $secret);

   $message = $res->getString();

   return response()->json(compact('message'));
}

1 ответ

Итак, на стороне сервера вы, очевидно, используете PHP с библиотекой Halite.

Я не очень знаком с Halite, но, глядя на его код, Crypto::seal() использует запечатанные коробки, так Box::open(anonymousCipherText: Data, recipientPublicKey: PublicKey, recipientSecretKey: SecretKey) -> Data? правильный способ расшифровки в Swift.

Однако Halite также, похоже, кодирует результат в виде строки BASE64 (вариант urlsafe).

Итак, вам нужно сначала расшифровать это. Или, и это будет более эффективным, не кодируйте зашифрованный текст. Если вам не нужно читать их вслух, ключи, вероятно, также не нужно кодировать.

Другие вопросы по тегам