安全持久性和IPC加密密钥

时间:2014-01-03 00:10:17

标签: security passwords go ipc unix-socket

我正在开发一个简单的命令行实用程序,它根据用户提供的密码加密/解密一个小文件。为了防止用户在短时间内反复重新输入他/她的密码短语,我需要提出一种临时缓存此密码短语(或派生的对称密钥)的解决方案。这类似于sudossh-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域套接字的情况下,保护是否类似于套接字文件的权限?如果有更好的方法,请告诉我。

两个准相关的问题:

  • 什么是良好的跨平台IPC /缓存机制?我专注于Linux,但Windows支持是一个优势。
  • 我知道将密码/密钥保存在内存中并不是100%安全,并且是一种鸡蛋问题。但是加密缓存的密钥会增加安全性吗?

1 个答案:

答案 0 :(得分:1)

如果您的目标是使用ssh-agentgpg-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。您可以使用此信息来决定是否要与它们进行通信。信息来自内核,因此无法由客户端伪造。