基于Web的登录使用ssl公钥/私钥


Web based login using ssl public/private key?

是否有可能通过web浏览器创建一个需要公钥/私钥的登录过程?公钥将存储在服务器上,私钥将由用户保存(并加密)。

我基本上想做一些类似于SSH所做的事情,但是通过web。可能是HTTP身份验证的自定义方法(而不是"Digest")。

我知道这可能是不可能的,用一个普通的浏览器,所以扩展使这项工作是可以接受的(Chrome/Firefox)。

理想情况下,密钥将被加密在u盘上。当u盘被拔下时必须是不可能登录的(不希望浏览器缓存它)。

在内部使用。

编辑:客户端证书将是我正在寻找的,但是我如何将这些证书存储在USB棒上?另外,是否有关于如何使用PHP验证用户身份的信息?

这是通过证书进行的客户端身份验证。
您的服务器应该配置为需要客户端证书,并配置一个信任库。
所有的浏览器都支持这个。
您只需要将具有私钥和证书的客户机密钥库导入到计算机的证书集。
对于windows,它是在internet选项

我怀疑你能在web应用程序中做到这一点。浏览器被操作系统沙盒化,你将无法让web应用程序检测到USB驱动器的存在,也无法用web应用程序读取任何数据。所以你需要浏览器来为你做这些,而它们不是这样设计的。

当您将客户端证书加载到浏览器中时,它被加载到证书存储中。这取决于浏览器和操作系统。在OSX上,它们进入KeyChain。在Windows上,有些将进入操作系统密钥库,有些将进入浏览器自己的密钥库(我相信Firefox就是这样工作的)。但是它们都不允许您定义外部密钥仓库,然后在读取和写入该驱动器时对您试图保护的密钥进行加密和解密。

如果你写了自己的桌面应用程序(本质上是你自己的浏览器)来为你做这些事情,你所做的事情才有可能实现。

您可以使用Adobe AIR应用程序来执行此操作。Adobe AIR支持从USB驱动器读取和写入,它支持加密数据库(128位AES/CBC加密与SQLite),在那里你可以存储你想要保护的数据,它是跨平台的。

使用任何这些解决方案,您可能会在需要确保USB密钥插入的要求时停止。这可能很难做到。如何阻止用户简单地将文件从USB密钥复制到硬盘,然后从那里使用密钥,这样他们就不需要使用USB密钥了?

要达到这种控制水平,您可能需要考虑真正的本地解决方案。c++、Objective-C或Java。Java将是唯一一个为您提供跨平台解决方案的语言。

如果USB密钥对最终用户来说是一种便利,而不是一种要求,那么Adobe AIR将是一个可靠的解决方案。如果没有,那么是时候温习一下桌面软件开发技能了。

以下是我如何在php中使用RSA公钥/私钥进行web登录:

  • 在注册时,服务器保存用户的公钥并给用户一个ID
  • 登录时,用户被要求输入他的ID和私钥

注册非常简单。

但是登录是这样完成的:

  • 服务器生成一个包含一些数据的字符串:随机字符串,当前时间,用户的ip
  • 该字符串使用AES加密两次,使用两个密码:nonce1 = pass2( pass1( string ) )
  • 同样的字符串用AES用两个密码再次加密,但顺序相反:nonce2 = pass1( pass2( string ) ),结果用用户的公钥加密:nonce2encrypted = encryptPubKeyRSA( userPubKey, nonce2 )

注:该字符串使用两个密码加密,以防止暴力攻击。

登录表单中有三个隐藏输入:nonce1nonce2encryptednonce2,没有值。

然后要求用户在<form>标签之外的文本区域输入他的私钥(以确保它不会在表单提交时发送到服务器), javascript将解密nonce2encrypted并将解密值设置为nonce2。然后用javascript从html中删除带有私钥的文本区域,只是为了确保它不会存储在浏览器的某个地方或发送到服务器。

服务器接收到nonce1nonce2,用这两个密码对它们进行解密。如果解密后的值相同,则用户收到cookie并登录。

注:该cookie还包含一些加密数据,例如用户ip。这将不允许窃取此cookie的人从其他ip登录。

你可以看到这个方法在行动(项目在github上)

客户端证书是答案。大多数/所有浏览器导入这些客户端证书为pkcs# 12。p12, .pfk)。

您可以使用公钥(.crt)、私钥(.key)和CA证书(.crt)将现有的x509证书转换为pkcs# 12文件。您可以使用以下命令在OpenSSL中执行此操作:

openssl pkcs12 -export -out client.p12 -inkey client.key -in client.crt -certfile ca.crt

如果您自签名证书,那么确保证书序列不同于其他证书是很重要的。如果它们相同,您可能会在尝试导入。p12文件时遇到错误(因此要注意openssl示例中的-set_serial)。

不幸的是,使证书移动/可移动的唯一跨平台方法是使用智能卡(使用pkcs# 11)。

在Mac OS X上,Safari和Chrome从密钥链访问它们的证书。实际上,您可以在USB闪存驱动器上创建自定义keychain (File -> New keychain)。在您创建了钥匙链之后,您可以简单地将。p12文件拖到您的钥匙链中。这样做的好处是,您可以控制访问哪些应用程序可以访问证书,并且您可以在一定数量的不活动后将钥匙链本身锁定。

在Safari中,这工作得很好。如果你拔掉闪存盘的插头,它会在几秒钟后停止发送证书。如果你把它插回去,它马上就能捡起来。如果您使用"Keychain Access"锁定证书,它会要求输入密码。它会阻止你在使用时正确弹出闪存盘,但一分钟后Safari会释放它的锁。

Chrome很挑剔。它将证书缓存几分钟。如果您锁定钥匙链,它将继续使用缓存的版本。如果你试图正确卸载闪存驱动器,它会告诉你Chrome正在使用它,直到你关闭它。如果你在Chrome运行时插入闪存盘,它将无法接收它。

看来Safari是唯一支持此功能的浏览器。Firefox和Opera都有自己的密钥库。

如果你想隐藏你的自定义钥匙链在闪存驱动器上,你可以创建一个不可见的文件夹,前缀是一个句号(像"./.keys")。创建钥匙链时,您可以通过按Command+Shift+"."在对话框窗口中查看不可见文件夹。

你的问题的答案是"今天不可能"。

这项技术以证书的形式存在,所有浏览器都支持。但是要达到你想要的效果,浏览器必须允许在用户界面的"密码管理器"部分添加和管理证书。人们会想要在不同的设备之间同步它们。

此外,网站也需要类似的更改,以便用户能够管理存储在网站上的公钥,而不是管理他们的密码。

这种系统的好处是你永远不需要把你的密码(私钥)发送到你正在登录的网站。但除此之外,您仍然可以使用密码进行今天的所有管理活动。