You haven’t used Harbor in a while, so you forgot your password. Reset the password by changing the database.

Analysis of the source code

Look at the harbor of source code, find the source generated password 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(a) 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]))
}
Copy the code

Viewing the user table

Enter the database container

docker exec -it harbor-db bash
Copy the code

Connecting to the database

postgres [ / ]$ psql
psql (9.620.)
Type "help" for help.
Copy the code

Switching databases

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

Viewing table structure

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()
Copy the code

Generate the password

By analyzing the source code and the data table structure, now write a password generation program.

The source code

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(a) hash.Hash{
        SHA1:   sha1.New,
        SHA256: sha256.New,
    }

    password string
    salt     string
    alg      string
)

func main(a) {
    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)
    iferr ! =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(a) string {
    return GenerateRandomStringWithLen(32)}Copy the code

use

Download: harbor – the password

# Automatically generate salt
./harbor-password -p yourpass

# specified salt
./harbor-password -p yourpass -salt yoursalt

Sha1 and SHA256 are supported. Sha256 is the default
./harbor-password -p yourpass -alg sha1
Copy the code