Migration of Web Clients with hashed secrets
Overview
This guide explains how to migrate Web Clients that use Basic Authentication when only the hashed versions of their secrets are available. We focus on configuring these secrets through our API, assuming the hashing algorithm and its parameters are known.
Configuring the Web Client with a hashed secret
To configure a Web Client using a hashed secret, utilize the hashed_client_secret
attribute in the Web Client creation request:
POST /api/v1/configuration/web-clients HTTP/1.1
Host: server.com
Content-Type: application/json
Authorization: Basic <your-credentials>
{
"name": "my-web-client",
"client_id": "my-client-id",
"hashed_client_secret": "$bcrypt$c=12$T/jBeKR12ikAWTPPZ5mj4Q$RUV/BRiDmssw1kAUu9MKWiQ4v2lYOWY"
...
}
Further details on the Web Client Configuration API can be found on the Web Clients API page.
Supported Hash Formats and Description
Our system adheres to the PHC format, supporting the following secure hashing algorithms:
- PBKDF2-SHA1
- Argon2id
- Bcrypt
PHC Format Explanation
The PHC string format is a modular system for specifying password hash parameters in a portable and compact way. It is structured as
follows: $identifier$params$salt$hash
, where:
identifier
specifies the hashing algorithm (e.g., bcrypt, pbkdf2-sha1, argon2id).params
defines operational parameters such as cost or iterations.salt
is the salt used in hashing, encoded in base64.hash
is the actual hash result, also encoded in base64.
Examples of PHC Formatted Hashes for each supported algorithm:
- PBKDF2-SHA1:
$pbkdf2-sha1$i=10000$test$E3B0M7MEBhwTsFDZAIA7hWQ2Zpc=
- Argon2id:
$argon2id$i=2,m=65536,p=1$dGVzdA==$otNQ21ttnzeFdwPncWePGZpLhNp6Tyss/r0RU3G+9sY=
- Bcrypt:
$bcrypt$c=12$T/jBeKR12ikAWTPPZ5mj4Q$RUV/BRiDmssw1kAUu9MKWiQ4v2lYOWY
Converting bcrypt to PHC Format
If your secret is stored in bcrypt format but not in a PHC-compliant structure, you may need to convert it. This conversion ensures compatibility with our system. Below is a Python script that demonstrates how to perform this conversion:
#!/usr/bin/env python3
import sys
def bcrypt_to_phc(bcrypt):
_, _, cost, salt_hash = bcrypt.split('$')
salt, hash = salt_hash[:22], salt_hash[22:]
translation_table = str.maketrans(
"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
)
salt_standard_b64 = salt.translate(translation_table)
checksum_standard_b64 = hash.translate(translation_table)
return f"$bcrypt$c={int(cost)}${salt_standard_b64}${checksum_standard_b64}"
print(bcrypt_to_phc(sys.argv[1]))
To convert a bcrypt hash to PHC format, run the script with the bcrypt hash as an argument:
$ ./bcrypt.py '$2a$12$R9h/cIPz0gi.URNNX3kh2OPST9/PgBkqquzi.Ss7KIUgO2t0jWMUW'
The output will be a PHC-formatted bcrypt hash:
$bcrypt$c=12$T/jBeKR12ikAWTPPZ5mj4Q$RUV/BRiDmssw1kAUu9MKWiQ4v2lYOWY