使用SSL证书验证我的站点上的用户身份

时间:2016-05-03 09:43:19

标签: authentication ssl ssl-certificate

我需要在我的网站上注册公司以获取电子采购系统。到目前为止,这些都是本地公司,我可以在实际上见到并提供凭证,但现在他们可以成为世界上任何地方的公司。

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

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

一旦他们拥有一个帐户,我应该只是请求我签发的凭据进行登录,还是以后所有登录都可以请求相同的证书文件?在这些特定的证书格式中,我可以请求或者我应该允许不同证书供应商提供的许多通用格式吗?

提前致谢。

1 个答案:

答案 0 :(得分:1)

遗憾的是,能够提供证书并不能证明什么。证书完全公开,任何人都可以获得任何网站的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,因为任何人都可以颁发证书并持有foo.com的私钥 - 它是提供真实性保证的证书的CA签名。

相关问题