Socketトランスポート層暗号化

2774 ワード

Periodic task systemは、タスクスケジューリングのコアコンポーネントとして100台以上のサーバで動作する必要があります.この場合、クライアントを認証する必要があります.そこで、転送層の暗号化を考えました.
まず、伝送層Transportを抽象化する
import           Data.ByteString           (ByteString)
import           Network.Socket            (Socket)
import qualified Network.Socket            as Socket (close)
import           Network.Socket.ByteString (recv, sendAll)

data Transport = Transport { recvData :: Int -> IO ByteString
                           , sendData :: ByteString -> IO ()
                           , close    :: IO ()
                           }

makeSocketTransport :: Socket -> IO Transport
makeSocketTransport sock =
  return Transport { recvData = recv sock
                   , sendData = sendAll sock
                   , close    = Socket.close sock
                   }

トランスポート層を定義するTransport.
  • recvDataデータ
  • を読み出す.
  • sendData送信データ
  • close伝送層
  • を閉じる.Socketをカプセル化した.
    トランスポート層XOR暗号化/dev/randomを用いてランダムなバイナリKEYを生成する
    dd if=/dev/random of=xor_key count=1024 bs=1
    

    次いで、このKEYを用いて、伝送層のデータを暗号化する.Lazy形式でKEYファイルを読み込む
    import qualified Data.ByteString.Lazy   as LB
    
    key 
    Transportにおいて、KEYは循環的に使用される必要があり、LB.cycleによって1つの循環のKEYが生成され、IORefに保存される.
    import           Data.IORef           (IORef, atomicModifyIORef', newIORef)
    
    send_key 
    XORのアルゴリズム
    import qualified Data.ByteString      as B
    
    xorBS :: IORef LB.ByteString -> B.ByteString -> IO B.ByteString
    xorBS ref bs = do
      xor'  atomicModifyIORef' ref (\v -> (LB.drop len v, LB.take len v))
    
     where  bs' = LB.fromStrict bs
            len = LB.length bs'
            xor' = B.pack . LB.zipWith xor bs'
    

    最終パッケージTransport
    xorSendData transport bs = xorBS send_key bs >>= sendData transport
    xorRecvData transport nbytes = xorBS recv_key =<< recvData transport nbytes
    
    makeXORTransport :: Transport -> Transport
    makeXORTransport transport = Transport { sendData = xorSendData transport
                                           , recvData = xorRecvData transport
                                           , close = close transport
                                           }
    

    締めくくり
    簡単なSocket伝送層暗号化はこのように完了した.KEYは、画像、ファイルなどの他の方法を用いて生成することができる.本文はXORの方式を実現しただけで,読者たちも試みたTLSなどの暗号化方式を実現することができる.
    関連コード:Transport.hs XOR.hs文章がいいと思ったら、あなたに役に立つと思ったら、私に注目してください.