好久没用 Harbor,把密码给忘记了,通过修改数据库重置一下密码吧。

分析源码

看了一下 harbor 的源码,找到生成密码的源码 src/common/utils/encrypt.go

package utils

import (
    "crypto/sha1"
    "crypto/sha256"
    "fmt"
    "hash"

    "golang.org/x/crypto/pbkdf2"
)

const (
    // 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,
}

// Encrypt encrypts the content with salt
func Encrypt(content string, salt string, encrptAlg string) string {
    return fmt.Sprintf("%x", pbkdf2.Key([]byte(content), []byte(salt), 4096, 16, HashAlg[encrptAlg]))
}

查看用户表

进入数据库容器

docker exec -it harbor-db bash

连接数据库

postgres [ / ]$ psql
psql (9.6.20)
Type "help" for help.

切换数据库

postgres=# \c registry
You are now connected to database "registry" as user "postgres".

查看表结构

registry=# \d harbor_user
                                           Table "public.harbor_user"
      Column      |            Type             |                           Modifiers                           
------------------+-----------------------------+---------------------------------------------------------------
 user_id          | integer                     | not null default nextval('harbor_user_user_id_seq'::regclass)
 username         | character varying(255)      | 
 email            | character varying(255)      | 
 password         | character varying(40)       | not null
 realname         | character varying(255)      | not null
 comment          | character varying(30)       | 
 deleted          | boolean                     | not null default false
 reset_uuid       | character varying(40)       | default NULL::character varying
 salt             | character varying(40)       | default NULL::character varying
 sysadmin_flag    | boolean                     | not null default false
 creation_time    | timestamp without time zone | default now()
 update_time      | timestamp without time zone | default now()
 password_version | character varying(16)       | default 'sha256'::character varying
Indexes:
    "harbor_user_pkey" PRIMARY KEY, btree (user_id)
    "harbor_user_email_key" UNIQUE CONSTRAINT, btree (email)
    "harbor_user_username_key" UNIQUE CONSTRAINT, btree (username)
Referenced by:
    TABLE "oidc_user" CONSTRAINT "oidc_user_user_id_fkey" FOREIGN KEY (user_id) REFERENCES harbor_user(user_id)
    TABLE "project" CONSTRAINT "project_owner_id_fkey" FOREIGN KEY (owner_id) REFERENCES harbor_user(user_id)
Triggers:
    harbor_user_update_time_at_modtime BEFORE UPDATE ON harbor_user FOR EACH ROW EXECUTE PROCEDURE update_update_time_at_column()

生成密码

通过分析源代码和数据表结构,现在来写一个生成密码的程序。

源码

package main

import (
    "crypto/rand"
    "crypto/sha1"
    "crypto/sha256"
    "flag"
    "fmt"
    "hash"

    "github.com/goharbor/harbor/src/lib/log"
    "golang.org/x/crypto/pbkdf2"
)

const (
    // SHA1 is the name of sha1 hash alg
    SHA1 = "sha1"
    // SHA256 is the name of sha256 hash alg
    SHA256 = "sha256"
)

var (
    HashAlg = map[string]func() hash.Hash{
        SHA1:   sha1.New,
        SHA256: sha256.New,
    }

    password string
    salt     string
    alg      string
)

func main() {
    flag.StringVar(&password, "p", "", "password")
    flag.StringVar(&salt, "salt", "", "salt")
    flag.StringVar(&alg, "alg", SHA256, "encrypt algorithm, support sha1 and sha256")
    flag.Parse()

    if salt == "" {
        salt = GenerateRandomString()
    }
    fmt.Printf("%x", pbkdf2.Key([]byte(password), []byte(salt), 4096, 16, HashAlg[alg]))
}

// GenerateRandomStringWithLen generates a random string with length
func GenerateRandomStringWithLen(length int) string {
    const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    l := len(chars)
    result := make([]byte, length)
    _, err := rand.Read(result)
    if err != nil {
        log.Warningf("Error reading random bytes: %v", err)
    }
    for i := 0; i < length; i++ {
        result[i] = chars[int(result[i])%l]
    }
    return string(result)
}

// GenerateRandomString generate a random string with 32 byte length
func GenerateRandomString() string {
    return GenerateRandomStringWithLen(32)
}

使用

下载:harbor-password

# 自动生成 salt
./harbor-password -p yourpass

# 指定 salt
./harbor-password -p yourpass -salt yoursalt

# 指定加密算法,支持 sha1 和 sha256,默认 sha256
./harbor-password -p yourpass -alg sha1