我正在开发一个简单的命令行实用程序,它根据用户提供的密码加密/解密一个小文件。为了防止用户在短时间内反复重新输入他/她的密码短语,我需要提出一种临时缓存此密码短语(或派生的对称密钥)的解决方案。这类似于sudo
和ssh-agent
等程序提供的功能。
到目前为止我提出的解决方案是一个单独的守护程序缓存程序,它跟踪加密文件(尽管通常只有一个文件)和相应的密钥。这些文件由校验和(SHA-256
)标识,与加密客户端的通信是使用Unix域套接字完成的。
这是我在Go中net/rpc
包的帮助下创建的RPC服务的简化摘录:
type Checksum [ChecksumSize]byte
type SumKeyPair struct {
Sum Checksum
Key []byte
}
type KeyReply struct {
Key []byte
Available bool
}
type Cache map[Checksum][]byte
// Fetches key that corresponds with file checksum
func (c Cache) RequestKey(sum Checksum, reply *KeyReply) error {
reply.Key, reply.Available = c[sum]
return nil
}
// Adds or updates key that corresponds with file checksum
func (c Cache) SetKey(pair SumKeyPair, reply *bool) error {
_, *reply = c[pair.Sum]
c[pair.Sum] = pair.Key
return nil
}
每次用户想要解密文件时都会调用 RequestKey
。每次提供正确的密码短语时都会调用SetKey
(使用更新的校验和)。
在像这样的流程之间传输敏感数据是否安全?在Unix域套接字的情况下,保护是否类似于套接字文件的权限?如果有更好的方法,请告诉我。
两个准相关的问题:
答案 0 :(得分:1)
如果您的目标是使用ssh-agent
或gpg-agent
的守护程序,那么您可能不希望进行RequestKey
操作。
设计其他代理程序时,私钥永远不会发送到客户端进程。因此,而不是ssh
从代理检索私钥,以便它可以执行基于挑战的身份验证,它将挑战发送给代理,然后代理返回准备好发送到服务器的签名版本的攻击。</ p >
简单地说,如果代理从未通过IPC机制发送私钥,则IPC机制不能用于窥探私钥。
如果您想进一步提高代理的安全性,如果您在Linux上使用UNIX域套接字,则可以使用SO_PEERCRED
套接字选项来查询您正在与之通话的人的身份:
func getPeerCred(conn net.Conn) (*syscall.Ucred, error) {
file, err := conn.(*net.UnixConn).File()
if err != nil {
return nil, err
}
defer file.Close()
return syscall.GetsockoptUcred(int(file.Fd()), syscall.SOL_SOCKET, syscall.SO_PEERCRED)
}
返回的Ucred
结构会告诉您套接字另一端的方的进程,用户和组ID。您可以使用此信息来决定是否要与它们进行通信。信息来自内核,因此无法由客户端伪造。