代码之家  ›  专栏  ›  技术社区  ›  Geoffrey

如何生成SSH代理签名响应

  •  1
  • Geoffrey  · 技术社区  · 8 年前

    我正在编写一个内部管理系统,该系统还需要实现SSH代理。到目前为止,我已经实施了 SSH_AGENTC_REQUEST_IDENTITIES SSH_AGENT_IDENTITIES_ANSWER SSH_AGENTC_SIGN_REQUEST 根据 https://tools.ietf.org/id/draft-miller-ssh-agent-00.html

    我的问题是如何签署请求,目前我只需要支持 ssh-rsa https://www.rfc-editor.org/rfc/rfc4253

    从我对本规范的理解来看 SSH\u AGENTC\u SIGN\u请求 消息需要使用签名 RSASSA-PKCS1-v1_5

    if msgType == SSH_AGENTC_SIGN_REQUEST:
      blobLen = struct.unpack('!I', sock.recv(4))[0]
      blob    = sock.recv(blobLen)
      dataLen = struct.unpack('!I', sock.recv(4))[0]
      data    = sock.recv(dataLen)
      flags   = struct.unpack('!I', sock.recv(4))[0]
    
      print("blob: %s\ndata: %s\n flags: %d" % (blob, data, flags))
    
      if base64.b64decode(server["public_key"]) != blob:
        sock.sendall(struct.pack('!IB', 1, SSH_AGENT_FAILURE))
        continue
    
      signed = rpc.root.signSSHData(server_id, data)
      if not signed:
        sock.sendall(struct.pack('!IB', 1, SSH_AGENT_FAILURE))
        continue
    
      buff = bytearray()
      buff.extend(struct.pack('!B', SSH_AGENT_SIGN_RESPONSE))
      packBytes(buff, bytes("ssh-rsa", "UTF-8"))
      packBytes(buff, signed)
      head = struct.pack('!I', len(buff))
    
      sock.sendall(head);
      sock.sendall(buff);
    

    rpc.root.signSSHData :

      def exposed_signSSHData(self, server_id, data):
        query = "SELECT private_key FROM servers WHERE deleted = 0 AND id = %s LIMIT 1"
        cursor = self.core.getDBC().cursor()
        cursor.execute(query, (server_id, ))
        row    = cursor.fetchone();
        if row is None:
          cursor.close()
          return False
    
        key    = self.core.decryptData(row[0])
        key    = RSA.importKey(key);
        h      = SHA.new(data)
        signer = PKCS1_v1_5.new(key)
        return signer.sign(h)
    

    更新1: 我想我可能已经弄明白了,似乎 data 是一个 SSH_MSG_USERAUTH_REQUEST 如RFC4252中所定义。我将更新我的应用程序,看看它如何运行。

    1 回复  |  直到 4 年前
        1
  •  1
  •   Geoffrey    8 年前

    我找到了解决方案,回复格式不正确,下面是更正的代码:

    if msgType == SSH_AGENTC_SIGN_REQUEST:
      blobLen = struct.unpack('!I', sock.recv(4))[0]
      blob    = sock.recv(blobLen)
      dataLen = struct.unpack('!I', sock.recv(4))[0]
      data    = sock.recv(dataLen)
      flags   = struct.unpack('!I', sock.recv(4))[0]
    
      if base64.b64decode(server["public_key"]) != blob:
        sock.sendall(struct.pack('!IB', 1, SSH_AGENT_FAILURE))
        continue
    
      sig = rpc.root.signSSHData(server_id, data);
      if not sig:
        sock.sendall(struct.pack('!IB', 1, SSH_AGENT_FAILURE))
        continue
    
      signature = bytearray()
      packBytes(signature, bytes("ssh-rsa", "UTF-8"))
      packBytes(signature, sig)
    
      buff = bytearray()
      buff.extend(struct.pack('!B', SSH_AGENT_SIGN_RESPONSE))
      packBytes(buff, signature)
      head = struct.pack('!I', len(buff))
    
      sock.sendall(head);
      sock.sendall(buff);
      continue