swift sodium Decrypt使用私钥

时间:2017-09-19 14:05:04

标签: php ios swift libsodium sodium

我在客户端使用Swift Sodium,因为我的服务器使用libsodium加密数据,然后通过API与我共享。

现在我有一个现有的私钥和一个String格式的公钥。我想现在使用Swift在iOS上解密加密数据。

如何使用我拥有的公钥和私钥生成钠密钥对?

理想情况下,我应该只使用私钥来解密数据。那么我该如何仅使用私钥作为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 个答案:

答案 0 :(得分:0)

所以,在服务器端,您显然正在使用PHP,并使用名为Halite的库。

我对Halite不太熟悉,但查看其代码,{{1}}使用密封框,因此{{1}}是在Swift中解密此代码的正确方法。

但是,Halite似乎也将结果编码为BASE64字符串(urlsafe变体)。

所以,你需要先解码它。或者,这将更有效,不要编码密文。除非你必须大声朗读它们,否则键也可能不需要编码。