nginx - lua的mongodb库auth验证方法耗费时间占请求的三分之二!请问大神怎么优化下呢

 mbe5757086 发布于 2022-10-25 06:52

验证的方法代码:

function dbmethods:auth_scram_sha1(username, password)
    local user = string.gsub(string.gsub(username, '=', '=3D'), ',' , '=2C')
    local nonce = ngx.encode_base64(string.sub(tostring(math.random()), 3 , 14))
    local first_bare = "n="  .. user .. ",r="  .. nonce
    local sasl_start_payload = ngx.encode_base64("n,," .. first_bare)
    
    r, err = self:cmd(attachpairs_start({
            saslStart = 1 ;
            mechanism = "SCRAM-SHA-1" ;
            autoAuthorize = 1 ;
            payload =  sasl_start_payload ;
         } , "saslStart" ) )
    if not r then
        return nil, err
    end
    
    local conversationId = r['conversationId']
    local server_first = r['payload']
    local parsed_s = ngx.decode_base64(server_first)
    local parsed_t = {}
    for k, v in string.gmatch(parsed_s, "(%w+)=([^,]*)") do
        parsed_t[k] = v
    end
    local iterations = tonumber(parsed_t['i'])
    local salt = parsed_t['s']
    local rnonce = parsed_t['r']

    if not string.sub(rnonce, 1, 12) == nonce then
        return nil, 'Server returned an invalid nonce.'
    end
    local without_proof = "c=biws,r=" .. rnonce
    local pbkdf2_key = pass_digest ( username , password )
    local salted_pass = pbkdf2_hmac_sha1(pbkdf2_key, iterations, ngx.decode_base64(salt), 20)
    local client_key = ngx.hmac_sha1(salted_pass, "Client Key")
    local stored_key = ngx.sha1_bin(client_key)
    local auth_msg = first_bare .. ',' .. parsed_s .. ',' .. without_proof
    local client_sig = ngx.hmac_sha1(stored_key, auth_msg)
    local client_key_xor_sig = xor_bytestr(client_key, client_sig)
    local client_proof = "p=" .. ngx.encode_base64(client_key_xor_sig)
    local client_final = ngx.encode_base64(without_proof .. ',' .. client_proof)
    local server_key = ngx.hmac_sha1(salted_pass, "Server Key")
    local server_sig = ngx.encode_base64(ngx.hmac_sha1(server_key, auth_msg))
    
    r, err = self:cmd(attachpairs_start({
            saslContinue = 1 ;
            conversationId = conversationId ;
            payload =  client_final ;
         } , "saslContinue" ) )
    if not r then
        return nil, err
    end
    parsed_s = ngx.decode_base64(r['payload'])
    parsed_t = {}
    for k, v in string.gmatch(parsed_s, "(%w+)=([^,]*)") do
        parsed_t[k] = v
    end
    if parsed_t['v'] ~= server_sig then
        return nil, "Server returned an invalid signature."
    end
    
    if not r['done'] then
        r, err = self:cmd(attachpairs_start({
            saslContinue = 1 ;
            conversationId = conversationId ;
            payload =  ngx.encode_base64("") ;
         } , "saslContinue" ) )
        if not r then
            return nil, err
        end
        if not r['done'] then
            return nil, 'SASL conversation failed to complete.'
        end
        return 1
    end
    return 1
end

完整文件github的地址:
https://github.com/LuaDist2/l...

3 个回答
  • 不需要每次都验证的吧?

    2022-10-26 14:24 回答
  • openresty有连接池,只有在首次与数据库建立连接的时候进行认证,应该没有太大影响吧

    2022-10-26 14:24 回答
  • 问一下这个怎么解决?加了账号密码每次请求查询都要验证,时间由30ms上升带500ms

    2022-10-26 14:24 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有