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 <- LB.readFile “xor_key”
在 Transport
中, KEY
需要循环使用,用 LB.cycle
来产生一个循环的 KEY
并将其保存在 IORef
中。
import Data.IORef (IORef, atomicModifyIORef', newIORef)
send_key <- newIORef $ LB.cycle key
recv_key <- newIORef $ LB.cycle 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
如果觉得文章好,对你有帮助就来关注我吧。