authentication - 使用 SSL 证书验证我网站上的用户身份

标签 authentication ssl ssl-certificate

我需要在我的网站上为电子采购系统注册公司。到目前为止,这些都是我可以亲自会面并提供证书的本地公司,但现在它们可以是位于世界任何地方的公司。

解决方案是通过在线注册流程提交第三方证书。所以说 Verisign 说他们是“X 公司”,所以我将他们注册为 X 公司并颁发证书。

如何在我的网站上实现此功能?我是否只是在他们上传证书文件的注册表中给他们一个字段?然后我要在我的后台手动检查这些证书吗?如何手动检查?有没有办法使这个过程自动化?

一旦他们有了帐户,我是应该简单地请求我颁发给他们的凭据来登录,还是所有以后的登录都可以请求相同的证书文件?在这些特定格式的证书中,我可以请求还是应该允许不同证书供应商提供的多种通用格式?

提前致谢。

最佳答案

很遗憾,能够提供证书并不能证明任何事情。证书是完全公开的,任何人都可以获得任何网站的SSL证书。证书包含公钥。需要证明相应私钥的所有权。

这是可行的,但它要求您的用户具备足够的技术知识,知道如何运行脚本和/或 OpenSSL 终端命令,以便他们可以使用私钥对某些内容进行签名。让用户上传他们的私钥当然是一个很大的禁忌,因为这意味着您现在可以充当用户,这需要对您有极大的信任才能在验证私钥后丢弃它。

从技术角度来看,您可以通过创建某种挑战(例如随机字符串)来进行验证,并让用户使用他们的私钥加密该字符串。如果用证书中的公钥解密这个字符串,得到原来的字符串,就知道他们拥有对应的私钥。

这是一个独立的 Ruby 脚本,它演示了这一点,其中的注释表明它的哪一部分在你这边运行,哪一部分在他们这边运行。

require "openssl"

## This happens on the client side. They generate a private key and a certificate.
## This particular certificate is not signed by a CA - it is assumed that a CA
## signature  check is already done elsewhere on the user cert.

user_keypair = OpenSSL::PKey::RSA.new(2048)


user_cert = OpenSSL::X509::Certificate.new
user_cert.not_before = Time.now
user_cert.subject = OpenSSL::X509::Name.new([
    ["C", "NO"],
    ["ST", "Oslo"],
    ["L", "Oslo"],
    ["CN", "August Lilleaas"]
  ])
user_cert.issuer = user_cert.subject
user_cert.not_after = Time.now + 1000000000 # 40 or so years
user_cert.public_key = user_keypair.public_key
user_cert.sign(user_keypair, OpenSSL::Digest::SHA256.new)

File.open("/tmp/user-cert.crt", "w+") do |f|
  f.write user_cert.to_pem
end


## This happens on your side - generate a random phrase, and agree on a digest algorithm

random_phrase = "A small brown fox"

digest = OpenSSL::Digest::SHA256.new

## The client signs (encrypts a cheksum) the random phrase

signature = user_keypair.sign(digest, random_phrase)


## On your side, verify the signature using the user's certificate.

your_user_cert = OpenSSL::X509::Certificate.new(File.new("/tmp/user-cert.crt"))
puts your_user_cert.public_key.verify(digest, signature, random_phrase + "altered")
# => falase
puts your_user_cert.public_key.verify(digest, signature, random_phrase)
# => true

## On your side - attempting to verify with another public key/keypair fails

malicious_keypair = OpenSSL::PKey::RSA.new(2048)
puts malicious_keypair.public_key.verify(digest, signature, random_phrase)

请注意,此脚本未考虑 CA 验证步骤 - 您显然还想验证用户的证书是否由 CA 验证,例如您提到的 Verisign,因为任何人都可以颁发证书并持有私有(private)证书foo.com 的 key - 它是提供真实性保证的证书的 CA 签名。

关于authentication - 使用 SSL 证书验证我网站上的用户身份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37000743/

相关文章:

iphone - [OAMutableURLRequest 参数] 崩溃

php - 使用 Sessions/SQL 进行简单登录

java - 执行 API 测试时忽略证书

android - 在哪里可以找到用户安装的证书 android 4.0 及更高版本

java - 设置https ssl连接的客户端请求超时(相互认证)

php - Laravel 基本 HTTP 身份验证检查返回 False

email - 从电子邮件信息验证电子邮件地址后自动登录

web-services - 大型 "in-house"企业 Web 应用程序是否在 LAN 上通过 SSL 运行?

java - 如何保留 OkHttp 中密码套件列表的顺序?

.net - Windows Server 2008 的 WebRequest 故障转移 TLS 1.1/1.2