如何生成 SSH 代理签名响应
How do I generate the SSH agent sign response
我正在写一个内部管理系统,也需要实现一个SSH代理。到目前为止,我已经正确地实现了 SSH_AGENTC_REQUEST_IDENTITIES
和 SSH_AGENT_IDENTITIES_ANSWER
,这导致 SSH 然后按照 https://tools.ietf.org/id/draft-miller-ssh-agent-00.html
发送 SSH_AGENTC_SIGN_REQUEST
我的问题是弄清楚如何签署请求,此时我只需要支持ssh-rsa
。我已尝试按照 https://www.rfc-editor.org/rfc/rfc4253 实施此操作,但我似乎无法生成将进行身份验证的回复。
根据我对本规范的理解,SSH_AGENTC_SIGN_REQUEST
消息的整个数据部分需要使用 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
是 RFC4252 中定义的 SSH_MSG_USERAUTH_REQUEST
。我会更新我的应用程序,看看进展如何。
我找到了解决方法,回复的格式不正确,下面是更正后的代码:
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
我正在写一个内部管理系统,也需要实现一个SSH代理。到目前为止,我已经正确地实现了 SSH_AGENTC_REQUEST_IDENTITIES
和 SSH_AGENT_IDENTITIES_ANSWER
,这导致 SSH 然后按照 https://tools.ietf.org/id/draft-miller-ssh-agent-00.html
SSH_AGENTC_SIGN_REQUEST
我的问题是弄清楚如何签署请求,此时我只需要支持ssh-rsa
。我已尝试按照 https://www.rfc-editor.org/rfc/rfc4253 实施此操作,但我似乎无法生成将进行身份验证的回复。
根据我对本规范的理解,SSH_AGENTC_SIGN_REQUEST
消息的整个数据部分需要使用 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
是 RFC4252 中定义的 SSH_MSG_USERAUTH_REQUEST
。我会更新我的应用程序,看看进展如何。
我找到了解决方法,回复的格式不正确,下面是更正后的代码:
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