2017-09-19 17 views
0

私のサーバーはlibsodiumを使用してデータを暗号化してからAPIを介して私と共有するので、クライアント側ではSwift Sodiumを使用しています。迅速なナトリウム秘密鍵を使用した復号化

今私は私と一緒にString形式の既存の秘密鍵と公開鍵を持っています。 Swiftを使用してiOS上の暗号化されたデータを解読したいと考えています。

私の持つ公開鍵と秘密鍵を使用してSodium Keyペアを生成するにはどうすればよいですか?

また、理想的には私は秘密鍵だけを使ってデータを復号化するべきです。では、私は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 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')); 
} 
+0

あなたの 'dataString'はどのような形式ですか?多分base64や他の形式なので、解読する前に解読する必要がありますか? – algrid

+0

@algrid暗号化された文字列です。その上にエンコーディングがないので、デコーディングは必要ありません。 –

答えて

0

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; 
} 

復号化ロジック、サーバー側、あなたは明らかと呼ばれるライブラリで、PHPを使用していますHalite。

私はHaliteに慣れていませんが、コードを見ると、Crypto::seal()は密閉ボックスを使用していますので、Box::open(anonymousCipherText: Data, recipientPublicKey: PublicKey, recipientSecretKey: SecretKey) -> Data?はこれをSwiftで解読する正しい方法です。

しかし、Haliteは結果をBASE64文字列(urlsafeの亜種)としてエンコードしているようです。

これを最初に解読する必要があります。または、これがより効率的になり、暗号文をエンコードしないでください。それらを大声で読まなければならない場合を除いて、鍵はおそらく符号化する必要はありません。

+0

私はそれをデコードしようとしましたが、デコードされたデータは常にnilなので、base64でエンコードされていないと仮定しています。私はこれを使用しました - 'let decodedData = Data(base64Encoded:dataString)' –

+0

正しいBASE64変種を使用していることを確認してください。上記のように、HaliteはデフォルトでBASE64のURLafeバリアントを使用しているようです。 –

+0

フランクのすべての亜種でチェックされています。私はそのbase64エンコードされた正直なところすべて無しだとは思わない –

関連する問題