Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何允许客户端使用某种类型的公钥指纹通过HTTP进行自我注册?_Http_Authentication_Key_Verification_Agent - Fatal编程技术网

如何允许客户端使用某种类型的公钥指纹通过HTTP进行自我注册?

如何允许客户端使用某种类型的公钥指纹通过HTTP进行自我注册?,http,authentication,key,verification,agent,Http,Authentication,Key,Verification,Agent,我正致力于用微型嵌入式Linux设备创建小型中继站。它们连接了一些传感器,并通过HTTP POST将数据传输回服务器。现在服务器只接受他们的消息以及唯一的ID(eth0的MAC地址) 我想把它扩展到包含某种类型的安全性。我希望能够以最少的配置部署这些小设备。我想将基本固件复制到设备上,在现场将其连接起来,然后进行自我注册。他们第一次连接时,我希望服务器和设备进行某种类型的协商,在那里我可以存储指纹。随后,我可以使用该指纹对设备进行身份验证/验证 这样,一旦一个设备注册了它的唯一ID,我就可以保证

我正致力于用微型嵌入式Linux设备创建小型中继站。它们连接了一些传感器,并通过HTTP POST将数据传输回服务器。现在服务器只接受他们的消息以及唯一的ID(eth0的MAC地址)

我想把它扩展到包含某种类型的安全性。我希望能够以最少的配置部署这些小设备。我想将基本固件复制到设备上,在现场将其连接起来,然后进行自我注册。他们第一次连接时,我希望服务器和设备进行某种类型的协商,在那里我可以存储指纹。随后,我可以使用该指纹对设备进行身份验证/验证

这样,一旦一个设备注册了它的唯一ID,我就可以保证该ID中的所有数据都来自同一个设备。如果一个胭脂设备或一组设备确实注册了,我只会删除它们(我将IP存储到,以便可以按未知范围删除并阻止它们)

我的问题是做这件事最好的方法是什么?我回想一下SSH指纹的想法,第一次连接到服务器时,您会得到一个服务器指纹。如果将来的请求生成不同的指纹,您将收到一个巨大的警告,并且如果服务器的密钥实际已重新生成,则必须手动从授权密钥文件中删除指纹(例如,您在重新安装时没有保存旧的SSH密钥)

HTTP是否可能有类似的功能,可能避免使用预共享密钥


如果重要的话,客户机正在运行Python2,他们连接的服务器主要是用Tomcat上的Scala编写的

基本上,您所需要做的就是告诉服务器公钥,然后用它对所有消息进行签名。如果您不想要预共享密钥,则服务器无法确保正在注册的新用户实际上是您的设备之一。但是,您仍然可以验证消息是否来自最初使用该标识符注册的同一设备

这个过程基本上是这样的:

  • 客户端生成新的密钥对(例如RSA公钥/私钥对)
  • 客户端向服务器注册,并发送其公钥。服务器存储此公钥
  • 当客户端发送消息时,它会生成其消息的签名,并将其附加到消息上。当服务器收到消息时,它会验证签名,以确保消息是由持有相应私钥的人发送的
  • PyCrypto中的代码如下所示:

    生成密钥对 生成签名 服务器应该按照先前存储的方式加载公钥,并使用您使用的Scala/Java crypto API提供的“验证”方法,并且仅在消息成功时才接受消息


    了解每种方法的注意事项很重要,因为各种技术只能防止某些类型的攻击。例如,上述方法无法防止“重播攻击”,即攻击者记录具有特定含义的消息,然后稍后将其重新传输到服务器。防止这种情况的一种方法是在经过哈希处理的消息中包含时间戳;另一种方法是使用适当加密的传输(例如SSL/TLS)。

    基本上,您需要做的就是告诉服务器公钥,然后用它对所有消息进行签名。如果您不想要预共享密钥,则服务器无法确保正在注册的新用户实际上是您的设备之一。但是,您仍然可以验证消息是否来自最初使用该标识符注册的同一设备

    这个过程基本上是这样的:

  • 客户端生成新的密钥对(例如RSA公钥/私钥对)
  • 客户端向服务器注册,并发送其公钥。服务器存储此公钥
  • 当客户端发送消息时,它会生成其消息的签名,并将其附加到消息上。当服务器收到消息时,它会验证签名,以确保消息是由持有相应私钥的人发送的
  • PyCrypto中的代码如下所示:

    生成密钥对 生成签名 服务器应该按照先前存储的方式加载公钥,并使用您使用的Scala/Java crypto API提供的“验证”方法,并且仅在消息成功时才接受消息

    了解每种方法的注意事项很重要,因为各种技术只能防止某些类型的攻击。例如,上述方法无法防止“重播攻击”,即攻击者记录具有特定含义的消息,然后稍后将其重新传输到服务器。防止这种情况的一种方法是在经过哈希处理的消息中包含时间戳;另一种方法是使用适当加密的传输(例如SSL/TLS)

    from Crypto.PublicKey import RSA
    key = RSA.generate(2048)
    private_key = key.exportKey()
    public_key = key.publickey().exportKey()
    # private_key is a string suitable for storing on disk for retrieval later
    # public_key is a string suitable for sending to the server
    # The server should store this along with the client ID for verification
    
    from Crypto.PublicKey import RSA
    from Crypto.Hash import SHA
    key = RSA.importKey(private_key)
    # where private_key is read from wherever you stored it previously
    digest = SHA.new(message).digest()
    signature = key.sign(digest, None)
    # attach signature to the message however you wish