详解nginx basic auth配置踩坑记

2019-10-17 17:34:15王冬梅

package crypt

/*
#define _GNU_SOURCE
#include <unistd.h>
*/
import "C"

import (
  "sync"
  "unsafe"
)

var (
  mu sync.Mutex
)


func Crypt(pass, salt string) (string, error) {
  c_pass := C.CString(pass)
  defer C.free(unsafe.Pointer(c_pass))

  c_salt := C.CString(salt)
  defer C.free(unsafe.Pointer(c_salt))

  mu.Lock()
  c_enc, err := C.crypt(c_pass, c_salt)
  mu.Unlock()

  if c_enc == nil {
    return "", err
  }
  defer C.free(unsafe.Pointer(c_enc))

  return C.GoString(c_enc), err
}

生成密码的具体实现:

func main() {
  des, err := crypt.Crypt("Elastic123", "in")
  if err != nil {
    fmt.Errorf("error:", err)
    return
  }

  sha512, err := crypt.Crypt("Elastic123", "$6$SomeSaltSomePepper$")
  if err != nil {
    fmt.Errorf("error:", err)
    return
  }

  fmt.Println("des:", des)
  fmt.Println("SHA512:", sha512)
}

经过实测,上述通过调用crypt函数生成nginx支持的加密密码实际可用,但是需要注意的是如果密码长度超过8位,则salt参数只能选择$id$salt$encrypted类型,在测试过程中就是因为踩了这点坑导致nginx只能校验密码的前8位,无语。

因为在编写go代码过程中调用了C函数库,这种方式也需要依赖服务器所处环境,因此最好的方式是采用go标准库中的函数对密码进行加密。

使用crypto函数库

go的crypto标准库封装了很多中加密算法,采用SHA加密算法进行密码加密的代码如下:

package util

import (
  "crypto/sha1"
  "encoding/base64"
)

func GetSha(password string) string {
  s := sha1.New()
  s.Write([]byte(password))
  passwordSum := []byte(s.Sum(nil))
  return base64.StdEncoding.EncodeToString(passwordSum)
}

测试过程中通过调用GetSha()函数生成了对密码加密的字符串,但是直接配置在nginx的conf/htpasswd文件中,reload nginx配置后测试验证密码是否生效,结果还是报错,原来如前文所述,SHA加密的密码必须带有“{SHA}”前缀才可以,再次修改配置后经过验证,成功地用代码生成了nginx支持的对密码加密的字符串。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易采站长站。