说明
今天手贱点了下 Profile 里的 change username,然后再次登录就一直提示验证错误了,于是有了本文
思路
帐号密码肯定是存在 pg 里面的,那么进入 pg 查看修改即可咯
登录 pg 容器操作
# docker exec -it harbor-db /bin/bash
连接数据库:
postgres [ / ]$ psql -h 127.0.0.1 -p 5432 -d postgres -U postgres
查看有哪些数据库:
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
--------------+----------+----------+-------------+-------------+-----------------------
notaryserver | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =Tc/postgres +
| | | | | postgres=CTc/postgres+
| | | | | server=CTc/postgres
notarysigner | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =Tc/postgres +
| | | | | postgres=CTc/postgres+
| | | | | signer=CTc/postgres
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
registry | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
进入数据库:
postgres=# \c registry;
查看数据库里的表:
registry=# \dt
List of relations
Schema | Name | Type | Owner
--------+--------------------------+-------+----------
public | access | table | postgres
public | admin_job | table | postgres
public | alembic_version | table | postgres
public | artifact | table | postgres
public | artifact_blob | table | postgres
...
public | harbor_user | table | postgres
...
这里的 harbor_user 表比较可疑,进去看看有哪些字段:
registry=# select * from harbor_user;
user_id | username | email | password | realname | comment | deleted | reset_uuid | salt | sysadmin_flag | creation_time | update_time | password_version
---------+-----------+-----------------------+----------------------------------+----------------+----------------+---------+------------+----------------------------------+---------------+----------------------------+----------------------------+------------------
2 | anonymous | anonymous@example.com | | anonymous user | anonymous user | t | | | f | 2020-12-08 09:33:42.526298 | 2020-12-08 10:27:16.581339 | sha1
1 | admin | admin@example.com | c24c0ec3e220ea5fda4a58ac6750649d | system admin | admin user | f | | qasbz0ctdynu8rnj8wi21cghv4iefimj | t | 2020-12-08 09:33:42.526298 | 2020-12-08 10:27:16.581339 | sha1
果然,帐号密码是存储在里面了,但是加密了,我该如何修改呢?
google 了下,千篇一律的写着如下的语句,然后原始密码是 Harbor12345:
update harbor_user set password='a71a7d0df981a61cbb53a97ed8d78f3e', salt='ah3fdh5b7yxepalg9z45bu8zb36sszmr' where username='admin';
这样更新一来有安全隐患,二来没办法定义我想要的密码(当然也可以事后再去 web 里面去修改下),那么就稍微探查下如何定义这个更新语句吧。
密码计算采用 pbkdf2 算法
参考源码:https://github.com/goharbor/harbor/blob/master/src/common/dao/user.go
// ChangeUserPassword ...
func ChangeUserPassword(u models.User) error {
u.UpdateTime = time.Now()
u.Salt = utils.GenerateRandomString()
u.Password = utils.Encrypt(u.Password, u.Salt, utils.SHA256)
var err error
if u.PasswordVersion == utils.SHA1 {
u.PasswordVersion = utils.SHA256
_, err = GetOrmer().Update(&u, "Password", "PasswordVersion", "Salt", "UpdateTime")
} else {
_, err = GetOrmer().Update(&u, "Password", "Salt", "UpdateTime")
}
return err
}
写一个 harbor 密码修改程序
package main
import (
"crypto/sha1"
"crypto/sha256"
"fmt"
"golang.org/x/crypto/pbkdf2"
"hash"
"math/rand"
)
// harbor admin 密码修改方法:
// update harbor_user set salt='', password='', password_version ='' where username='admin';
const (
// EncryptHeaderV1 ...
EncryptHeaderV1 = "<enc-v1>"
// SHA1 is the name of sha1 hash alg
SHA1 = "sha1"
// SHA256 is the name of sha256 hash alg
SHA256 = "sha256"
)
// HashAlg used to get correct alg for hash
var HashAlg = map[string]func() hash.Hash{
SHA1: sha1.New,
SHA256: sha256.New,
}
func GenerateRandomStringWithLen(length int) string {
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
l := len(chars)
result := make([]byte, length)
_, err := rand.Read(result)
if err != nil {
fmt.Printf("error reading random bytes: %v", err)
}
for i := 0; i < length; i++ {
result[i] = chars[int(result[i])%l]
}
return string(result)
}
func Encrypt(content string, salt string, encrptAlg string) string {
return fmt.Sprintf("%x", pbkdf2.Key([]byte(content), []byte(salt), 4096, 16, HashAlg[encrptAlg]))
}
func main() {
// 这要设置这里的明文密码变量,就可以生成对应 salt、password 信息
password := "123456"
salt := GenerateRandomStringWithLen(32)
passwordEncry := Encrypt(password, salt, SHA256)
fmt.Printf("明文密码: %s\nsalt: %s\npassword: %s\npassword_version: sha256\n", password, salt, passwordEncry)
}
只要修改这个脚本里的 password
变量,就可以生成 update 语句
# go run main.go
现在可以安心的数据库修改密码,将执行产生的字符串带入下面的单引号内即可:
registry=# update harbor_user set salt='', password='', password_version ='' where username='admin';
网友评论