---
title: Password encoding
description: PingOne supports the following Key Derivation Functions (KDF) and crytographic ciphers as methods for password encoding:
component: pingone-api
page_id: pingone-api:platform:reference/password-encoding
canonical_url: https://developer.pingidentity.com/pingone-api/platform/reference/password-encoding.html
section_ids:
  pre-encoded-passwords: Pre-encoded passwords
  generating-the-salt: Generating the salt
  pbkdf2-encoding: PBKDF2
  pbkdf2-parameters-for-pingone: PBKDF2 parameters for PingOne
  argon2-encoding: Argon2
  argon2-parameters-for-pingone: Argon2 parameters for PingOne
  scrypt-encoding: Scrypt
  encoding-details: Encoding details
  scrypt-parameters-for-pingone: Scrypt parameters for PingOne
  SCRYPT_RFC7914-encoding: Scrypt RFC-7914
  scrypt-rfc-7914-parameters-for-pingone: Scrypt RFC-7914 parameters for PingOne
  bcrypt-encoding: Bcrypt
  bcrypt-parameters-for-pingone: BCrypt parameters for PingOne
  mscrypto-encoding: MSCrypto library
  mscrypto-parameters-for-pingone: MSCrypto parameters for PingOne
  ssha-encoding: SSHA methods
  ssha-parameters-for-pingone: SSHA parameters for PingOne
---

# Password encoding

PingOne supports the following Key Derivation Functions (KDF) and crytographic ciphers as methods for password encoding:

| Method                                      | PingOne Identifier |
| ------------------------------------------- | ------------------ |
| [PBKDF2](#pbkdf2-encoding)                  | `{PBKDF2}`         |
| [ARGON2](#argon2-encoding)                  | `{ARGON2}`         |
| [MSCrypto library](#mscrypto-encoding)      | `{MSKCC_PBKDF2}`   |
| [Scrypt](#scrypt-encoding)                  | `{SCRYPT}`         |
| [Scrypt RFC-7914](#SCRYPT_RFC7914-encoding) | `{SCRYPT_RFC7914}` |
| [BCrypt](#bcrypt-encoding)                  | `{BCRYPT}`         |
| [SSHA](#ssha-encoding)                      | N/A                |

The PingOne identifier for the method must be pre-pended to the encoding generated. Refer to the discussion of the specific method for the format.

The common password-encoding use cases for the PingOne Platform APIs are:

* [CREATE User (Import)](../users/users-1/create-user-import.html)

* [PUT Update password (Set)](../users/user-passwords/update-password-set.html)

## Pre-encoded passwords

Pre-encoded passwords must use the LDAP `userPassword` syntax supported by PingDirectory and other directory servers. For more information about the LDAP `userPassword` attribute, refer to [Hashed attribute values for `userPassword`](https://datatracker.ietf.org/doc/html/draft-stroeder-hashed-userpassword-values). Note that in this specification, the `userPassword` syntax represented as `userpasswordvalue = cleartext-password / prefix b64-hashandsalt` should be read as:

`userpasswordvalue = cleartext-password`

or

`userpasswordvalue = prefix b64-hashandsalt`

If a pre-encoded password isn't accepted by PingOne, it doesn't conform to either of these encoding schemes.

## Generating the salt

All of the encoding methods supported by PingOne require a `salt` to randomize the hashed value generated by the Hash-based Message Authentication Code (HMAC) used. Use only cryptographically strong random number generators (CSPRNG) to generate the `salt`. You'll generally find this in the cryptography library for your language and platform. Some of the most common are:

| Language/Platform | Description                                                                                                                            |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Linux and macOS   | The `/dev/random` or `/dev/urandom` sources.                                                                                           |
| Windows           | The `BCryptGenRandom` function from the Cryptography API: Next Generation (CNG) or higher level cryptography libraries.                |
| C#                | `System.Security.Cryptography.RandomNumberGenerator.Create()` from .NET Framework or .NET Core.                                        |
| Python            | Either `os.urandom()` or the secrets library.                                                                                          |
| Java              | The `java.security.SecureRandom` system class.                                                                                         |
| JavaScript        | Either `window.crypto.getRandomValues(Uint8Array)` for client side (Web browser), or `crypto.randomBytes()` for server-side (Node.js). |

## PBKDF2

PBKDF2 is a Key Derivation Function (KDF) described in [RFC 2898](https://www.ietf.org/rfc/rfc2898.txt). The standard format is:

```text
key = pbkdf2(password, salt, iterations, hash-function, derived-key-length)
```

PingOne APIs require a slightly modified version of this format, where the PingOne identifier for the encoding method is pre-pended to a Base64 encoding of the parameters:

```text
"{PBKDF2}" + base-64-encode(`version-hex`, `salt-length-hex`, `salt`, `iterations-hex`, `encoded-password`)
```

Any spaces in the hex values are ignored.

The resulting encoding that can be passed to PingOne APIs will then look similar to this:

```json
{PBKDF2}ARDCg7vxrqqSDV/UzQ5N9j+XJxDv0E64J9X5aHSZk4108X3esUoaKqGJePteFKJxT6qPkQ==
```

### PBKDF2 parameters for PingOne

Spaces are ignored in the hexadecimal values.

| Parameter          | Description                                                                                                                                                                                                                                                                      |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `encoded-password` | The user password. The password is assumed to be encoded.                                                                                                                                                                                                                        |
| `version-hex`      | A hexadecimal encoding of the version identifier for the PKDF2 and the HMAC combination to use. The version identifier can be any one of:\* 00 if PBKDF2WithHmacSHA1\* 01 if PBKDF2WithHmacSHA256\* 02 if PBKDF2WithHmacSHA384\* 03 if PBKDF2WithHmacSHA512                      |
| `salt-length-hex`  | A hexadecimal encoding of the length of the `salt`. This must be between 8 and 127 characters in length.                                                                                                                                                                         |
| `salt`             | A securely-generated cryptographically strong random number.                                                                                                                                                                                                                     |
| `iterations-hex`   | A hexadecimal encoding of the number of iterations to repeat the HMAC identified in `version-hex` (for example, 10,000). This can be between zero and 2,147,483,647. In general, use the maximum number of iterations that's acceptable for the performance of your application. |

## Argon2

Argon2 is a KDF described in [RFC 9106](https://datatracker.ietf.org/doc/rfc9106/). The standard format is similar to this:

```text
argon2.hash(password, type, iterations, memory, parallelism, hash_len, salt)
```

PingOne APIs require a slightly modified version of this format:

```text
"{ARGON2}" + type + version, memory, iterations, parallelism
```

The resulting encoding that can be passed to PingOne APIs will then look similar to this:

```text
$argon2i$v=19$m=64,t=2,p=8$d2pLMjlIUWk2eGU2OFZtVA$dr9M3P+yMs4qv/eFyh5WYw
```

### Argon2 parameters for PingOne

| Parameter     | Description                                                                                                                                                                                                                                 |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `password`    | The user password to encode.                                                                                                                                                                                                                |
| `type`        | One of the supported Argon2 types: Argon2i, Argon2d, Argon2id.                                                                                                                                                                              |
| `version`     | Specified as `v=`. The current version is decimal 19. Typically, this is unspecified, and defaults to the current version.                                                                                                                  |
| `memory`      | Specified as `m=`. The amount of memory to use in kilobytes. In general, use the maximum amount of memory that's acceptable for the performance of your application.                                                                        |
| `iterations`  | The number of iterations that's acceptable for the performance of your application. Typically, start with a 2 - 4 iterations, and modify this based on the desired execution time. The number of iterations must be between 1 and 2^32 − 1. |
| `parallelism` | The degree of parallelism to use is determined by the number of CPU cores on the server. Double the number of CPU cores to get the value here.                                                                                              |
| `salt`        | A securely-generated cryptographically strong random number used to salt the specified parameters. The salt length must be between 8 and 2^32 − 1 byte.                                                                                     |
| `hash-len`    | The desired hashed output length in bytes. Applied to the specified parameters.                                                                                                                                                             |

Refer to the [Argon2 Hash Generator](https://argon2.online/) to generate examples.

## Scrypt

Scrypt is described in [RFC 7419](https://tools.ietf.org/html/rfc7914.html). Like other KDFs, Scrypt is designed to be expensive, so that attacks against Scrypt-encoded passwords are also expensive. However, Scrypt is different from other KDF algorithms because it is designed to consume a substantial amount of memory during the course of encoding a password, and to require pseudorandom access to portions of that memory. This makes the cost of generating a password dependent upon memory access latency in addition to CPU performance, and reduces the ability to parallelize password cracking attempts.

PingOne uses the "c2NyeXB0" format, where c2NyeXB0 is the base64-encoded representation of "scrypt".

The resulting encoded string is base64-encoded, and the unencoded value always starts with the bytes "scrypt", and is "c2NyeXB0".)

PingOne APIs require a slightly modified version of the c2NyeXB0 format, where the PingOne identifier for the encoding method is pre-pended to the formatting identifier "c2NyeXB0":

```text
"{Scrypt}" + base-64-encode("scrypt", the-zero-byte, logN, r, p, salt, encoded-password)
```

### Encoding details

In the aggregated parameter values `"scrypt" + the-zero-byte + logN + r + p + salt`:

* The first 16 bytes is the first half of the SHA-256 encoding.

* Apply the HMAC-SHA-256 algorithm to the first 64 bytes

* Append the final 32 bytes to the final encoding.

The initialization key for the HMAC-SHA-256 algorithm is the last 32 bytes of the SCRYPT algorithm output, using the specified values for `encoded-password`, `salt`, `logN`, `r`, `p`, and a 64 byte block size.

The string that can be passed to PingOne APIs will then look similar to this:

```json
{Scrypt}c2NyeXB0/UzQ5N9j+XJxDv0E64J9X5aHSZk4108X3esUoaKqGJePteFKJxT6qPkQ==
```

### Scrypt parameters for PingOne

There is a 32 byte salt parameter:

* logN is one byte

* r and p are both 4 bytes

* logN, r, and p use two's complement representation

| Parameter          | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `encoded-password` | The user password to encode. This also is assumed to be encoded by the user.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `logN`             | A 1 byte value (two's complement) for the exponent to use for the CPU/memory cost factor. The cost factor must be a power of two, so the value of this property represents the power to which two is raised. The CPU/memory cost factor specifies the number of iterations required for encoding the password, and also affects the amount of memory required during processing. A higher cost factor requires more processing and more memory to generate a password, which makes attacks against the password more expensive. The value must be less than `128*r/8`, where `r` represents the configured block size. The amount of memory that will be consumed in the course of generating the password is `128*2^N*r` bytes, where `N` represents the CPU/memory cost factor exponent and `r` represents the configured block size. |
| `r`                | A 4 byte value (two's complement) for the block size for the digest that will be used in the course of encoding passwords. Increasing the block size while keeping the CPU/memory cost factor constant will increase the amount of memory required to encode a password, but it also increases the ratio of sequential memory access to random memory access (sequential memory access is generally faster than random memory access). The value must be greater than or equal to one.                                                                                                                                                                                                                                                                                                                                                  |
| `p`                | A 4 byte value (two's complement) for the number of times that Scrypt is to perform the entire encoding process to produce the final result. The amount of processing required to encode a password increases linearly with the value of this parameter. If an attacker uses an Scrypt implementation that supports the use of multiple threads to perform multiple encodings in parallel, then it also linearly increases the amount of memory required.                                                                                                                                                                                                                                                                                                                                                                               |
| `salt`             | A securely-generated cryptographically strong random number used to salt the specified parameters. The salt length is 32 bytes.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |

## Scrypt RFC-7914

Scrypt RFC-7914 supports a configurable salt, and uses the RFC-compliant encoding scheme described in [RFC 7914](https://datatracker.ietf.org/doc/html/rfc7914.html). It's designed to prevent GPU, FPGA, and ASIC attacks, and supercedes the older encoding scheme used by [Scrypt](#scrypt-encoding).

Like the older Scrypt, Scrypt RFC-7914 is designed to be expensive, so that attacks against Scrypt RFC-7914 encoded passwords are also expensive. It's designed to consume a substantial amount of memory during the course of encoding a password. This makes the cost of generating a password dependent upon memory access latency in addition to CPU performance, and reduces the ability to parallelize password cracking attempts.

The PingOne format is:

```text
"{SCRYPT_RFC7914}" version, N + r + p, base-64-encode(S, P), encoded-password
```

For each step, the memory is accessed in dependent order, so memory access speed is the bottleneck. The memory required for Scrypt RFC-7914 key derivation is calculated as:

```
128*r*2^N, and must be <= 128 MiB.
```

### Scrypt RFC-7914 parameters for PingOne

| Parameter          | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `version`          | The Scrypt RFC-7914 algorithm version. Currently, this must be "s0".                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `N`                | The hexadecimal string for a 1 byte value (two's complement) for the exponent to use for the CPU/memory cost factor. This must be from 1-17. The cost factor must be a power of two, so the value of this property represents the power to which two is raised. The CPU/memory cost factor specifies the number of iterations required for encoding the password, and also affects the amount of memory required during processing. A higher cost factor requires more processing and more memory to generate a password, which makes attacks against the password more expensive. The value must be less than `128*r/8`, where `r` represents the configured block size. The amount of memory that will be consumed in the course of generating the password is `128*2^N*r` bytes, where `N` represents the CPU/memory cost factor exponent and `r` represents the configured block size. |
| `r`                | The hexadecimal string for a 4 byte value (two's complement) for the block size for the digest that will be used in the course of encoding passwords. This must be from 1-8.Increasing the block size while keeping the CPU/memory cost factor constant will increase the amount of memory required to encode a password, but it also increases the ratio of sequential memory access to random memory access (sequential memory access is generally faster than random memory access). The value must be greater than or equal to one.                                                                                                                                                                                                                                                                                                                                                    |
| `p`                | The hexadecimal string for a 4 byte value (two's complement) for the number of times that Scrypt RFC-7914 is to perform the entire encoding process to produce the final result. This must be 1.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `S`                | A securely-generated cryptographically strong random number used to salt the specified parameters. The salt length is 1-64 bytes.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `P`                | A Base64-encoded passphrase. The length is 1-32 bytes.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `encoded-password` | The user password, assumed to be encoded.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |

An example of the use of the parameters is:

```
100801 (N = 0x10 = 16, r = 0x08 = 8, p = 0x01 = 1)
```

The string passed to PingOne APIs might then look similar to this:

```json
{SCRYPT_RFC7914}$s0$100801$a...=$a...=
```

## Bcrypt

BCrypt is a KDF based on the Blowfish cipher, and incorporates the Blowfish HMAC to hash the password. The standard format is:

```text
key = BCRYPT(password, cost, salt)
```

PingOne APIs require a slightly modified version of this format:

```text
"{BCRYPT}" + "$" + algorithm + "$" + cost + "$" + base-64-encode(salt) + base-64-encode-minus-one(key0)
```

|   |                                                                                                                                                                                      |
| - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|   | BCrypt doesn't use the standard base-64 encoding. The encoding algorithm is the same, but the alphabet used is permuted and the plus symbol (+) is replaced by the period symbol (.) |

The resulting encoding that can be passed to PingOne APIs will then look similar to this:

```json
{BCRYPT}$2y$10$xUtlkL33uoLU3jU7M7lkNOb0PbQQ7lKNqKuJLnZa4AzvXRWSq5Vxe
```

### BCrypt parameters for PingOne

Spaces are ignored in the hexadecimal values.

| Parameter                        | Description                                                                                                                                                                                                                                                                                                |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `$`                              | The prefix indicating a parameter.                                                                                                                                                                                                                                                                         |
| `algorithm`                      | The version of BCrypt to use. Generally, this should be "$2a". However, this can be any one of the versions: 2a, 2b, 2x, 2y. The versions 2x and 2y are relevant only if you've been using `crypt_blowfish`, a PHP implementation of BCrypt. The version 2b is relevant only if you've been using OpenBSD. |
| `cost`                           | A two digit number between 4 and 31 (inclusive). If the cost is less than 10, then prepend a zero (for example, 6 -> 06). This indicates the number of iterations to repeat the HMAC. In general, use the maximum number of iterations that's acceptable for the performance of your application.          |
| `base-64-encode(salt)`           | A securely-generated cryptographically strong random number.                                                                                                                                                                                                                                               |
| `base-64-encode-minus-one(key0)` | This is the base64 encoding algorithm with the final byte of the base64 encoding removed. The argument `key0` is the encrypted key (for example, BCrypt(password, cost, salt)), except the last byte is replaced with "0x00".                                                                              |

## MSCrypto library

Use the Microsoft method [Crypto.hashPassword()](https://learn.microsoft.com/en-us/dotnet/api/system.web.helpers.crypto.hashpassword) to encode passwords, then import those passwords into PingOne using the `{MSKCC_PBKDF2}` method.

MSCrypto uses PBKDF2 with HMAC-SHA1, 128-bit salt, 256-bit key length, and 1000 iterations.

PingOne APIs require this format:

```text
"{MSKCC_PBKDF2}" + base-64-encode(0x00 + salt + digest(password, salt-128, iterations, key-length))
```

Any spaces in the hex values are ignored.

The resulting encoding that can be passed to PingOne APIs will then look similar to this:

```json
{MSKCC_PBKDF2}ARDCg7vxrqqSDV/UzQ5N9j+XJxDv0E64J9X5aHSZk4108X3esUoaKqGJePteFKJxT6qPkQ==
```

### MSCrypto parameters for PingOne

Spaces are ignored in the hexadecimal values.

| Parameter    | Description                                                                                                                                                                                                                                               |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `0x00`       | A byte of zeros.                                                                                                                                                                                                                                          |
| `salt`       | A securely-generated cryptographically strong random number.                                                                                                                                                                                              |
| `digest`     | The PBKDF2 algorithm.                                                                                                                                                                                                                                     |
| `password`   | The user password. The password is assumed to be encoded.                                                                                                                                                                                                 |
| `salt-128`   | A securely-generated cryptographically strong random number of 128 bits.                                                                                                                                                                                  |
| `iterations` | A hexadecimal encoding of the number of iterations to repeat the HMAC-SHA1 (for example, 10,000). This can be between zero and 2,147,483,647. In general, use the maximum number of iterations that's acceptable for the performance of your application. |
| `key-length` | 256 bits.                                                                                                                                                                                                                                                 |

## SSHA methods

The SSHA algorithms incorporate the SHA cryptographic hash functions to hash the password. The PingOne-specific format for all of the SSHA variants is:

```text
"{SSHA-variant}" + base-64-encode(digest(password + salt) + salt )
```

The plus sign (+) indicates concatenation.

In addition, PingOne supports the following formats for both SHA256 and SHA1. The other variants do not support these formats.

```text
"{SSHA-variant}" + base-64-encode( digest(password + salt) + salt )
"{SSHA-variant}" + base-64-encode( digest(salt + password) + salt )
```

|   |                                                                                                                                                                                                                                 |
| - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | PingOne does not support the following formats for any of the SSHA variants:```text
"{SSHA-variant}" + base-64-encode( salt + digest(password + salt) )
"{SSHA-variant}" + base-64-encode( salt + digest(salt + password) )
``` |

### SSHA parameters for PingOne

| Parameter      | Description                                                                                  |
| -------------- | -------------------------------------------------------------------------------------------- |
| `SSHA-variant` | The SSHA variant to use. This can be one of the following: SSHA1, SSHA256, SSHA384, SSHA512. |
| `digest`       | The password encoding using the specified SSHA variant.                                      |
| `password`     | The user password to encode.                                                                 |
| `salt`         | A securely-generated cryptographically strong random number.                                 |
