Bulk import ForgeRock users with PBKDF2 password hash

For those interested in bulk importing users from ForgeRock, you may find this helpful.

Here is the ForgeRock documentation for how hashed passwords are stored in ForgeRock LDAP (DS).

In my example, we were using PBKDF2 (PBKDF2-HMAC-SHA1):
"{PBKDF2}" <iterations> ":" base64(<digest> <salt>)

With this example hashed password in ForgeRock. {PBKDF2}100000:7URh5W8BL4O7GkNjLC1LhueVo5C2qu/TX2hzZw==

With this corresponding plain text password:
Ehgz2B@rVr

I learned that the ForgeRock v6.5 key length used for pbkdf2-sha1 is 20 bytes. Your Auth0 user import file would look likeā€¦

[
    {
    	"user_id": "2000",
        "email": "user.name@mydomain.me",
        "given_name": "User",
	"family_name": "Name",
        "name" : "User Name",
        "custom_password_hash": {
            "algorithm": "pbkdf2",
            "hash": {
                "value": "$pbkdf2-sha1$i=100000,l=20$tqrv019oc2c$7URh5W8BL4O7GkNjLC1LhueVo5A",
                "encoding": "utf8"
            },
            "password": {
              "encoding": "utf8"
            }
        }

    }
]

And here is a golang script for computing the salt and digest that go into the json file.

package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	//ForgeRock format for storing a hashed password with pbkdf2-hmac-sha1
	//{PBKDF2}100000:7URh5W8BL4O7GkNjLC1LhueVo5C2qu/TX2hzZw==
	b64digestAndSalt := "7URh5W8BL4O7GkNjLC1LhueVo5C2qu/TX2hzZw=="
	digestAndSalt, _ := base64.StdEncoding.DecodeString(b64digestAndSalt)
	salt := digestAndSalt[len(digestAndSalt) - 8:]
	digest := digestAndSalt[0:len(digestAndSalt) - 8]
	b64Salt := base64.RawStdEncoding.EncodeToString(salt)
	b64Digest := base64.RawStdEncoding.EncodeToString(digest)
	fmt.Printf("base64 salt (no-padding): %s\n", b64Salt)
	fmt.Printf("base64 digest (no-padding): %s\n", b64Digest)
}

Hopefully that saves someone else some time.

Thanks for sharing that with the rest of community!