---
title: 'Tutorial: Understanding Local Password Hashing in Access Server'
canonical: https://openvpn.net/as-docs/tutorials/tutorial--local-password-hashing/
product: Access Server Docs
description: Understand Access Server's password hashing formats with this tutorial.
---

# Tutorial: Understanding Local Password Hashing in Access Server

## Overview

Access Server stores local user passwords as secure cryptographic hashes rather than plaintext. The hashing format used depends on your Access Server version and configuration. Understanding these formats can help you troubleshoot authentication issues, verify user entries, and ensure your deployment follows current security best practices.

This tutorial explains how Access Server stores password hashes, how to identify the format you’re seeing, and what to expect when comparing hashes across versions.

## Prerequisites

- An installed Access Server.
- Console access with the ability to get root privileges.

## Step 1: Understand pvt\_password\_digest

Access Server stores the hash of a user's password in the property:

```
pvt_password_digest
```

This value appears when querying user properties with `sacli` or when viewing the Access Server configuration database.

**Example user properties**

1. Connect to the console and get root privileges.
2. Switch to the scripts directory:

   ```
   cd /usr/local/openvpn_as/scripts/
   ```
3. Get user properties:

   ```
   ./sacli UserPropGet
   ```
4. Example output:

   ```
   "brandonqa": {
     "pvt_password_digest": "<hash value>",
     "type": "user_connect"
   }
   ```

   - The value is **never the user's actual password**. It's a one-way hash created using one of several supported algorithms.

## Step 2: Learn the hash formats

Access Server uses three main hashing formats, with each format storing the hash differently:

1. **SHA-256**.
2. **PBKDF2** (default in Access Server 2.10.1+)
3. **SCrypt** (optional, supported in Access Server 2.11.0+)

### SHA-256 format (Access Server 2.x → 2.9.x default

Example from Access Server 2.9.6:

```
a69e46f0bf641ec95da54e3c58116d4280ad478221fa3ae759a6b83ff28a6e3d
```

**Details:**

- 32 bytes (256 bits)
- Hex-encoded
- No salt stored with the hash
- No iteration count

**Characteristics:**

- Fast hashing algorithm.
- Secure when originally implemented, but no longer recommended for password storage because modern hardware can brute-force it more easily.

### PBKDF2 format (Access Server 2.10.1+ default)

Example:

```
$P$QHoQZ4rFNCXe/ebBogcb5A==$DAaBiGViXSecybPiUx6pq47LZ6XfNTx6fDroRleSJXw=
```

This format consists of **three components**:

```
<$P$><salt>$<hash>
```

**Breakdown:**

- **Prefix:** `$P$`
  - Indicates **PBKDF2**.
- **Salt:** `QHoQZ4rFNCXe/ebBogcb5A==`
  - Base64 encoded
  - 32 bytes
- **Hash:** `DAaBiGViXSecybPiUx6pq47LZ6XfNTx6fDroRleSJXw=`
  - Base64 encoded
  - 32 bytes

**Characteristics:**

- Uses key stretching (many iterations).
- Much stronger than SHA-256 for password storage.
- Default in Access Server 3.0.0 and later.

### SCrypt format (Access Server 2.11.0+ optional)

Example:

```
$S$2Qimw8oLAgCcaZFAuLJ8RA==$7NsNN2WPDCCwd74j59sNlF1q5yW+GFFFOLVyB/WKZBc=
```

This format consists of **three components**:

```
<$S$><salt>$<hash>
```

**Breakdown:**

- **Prefix:** `$S$`
  - Indicates **SCrypt**.
- **Salt:** `2Qimw8oLAgCcaZFAuLJ8RA==`
  - Base64
  - 16 bytes
- **Hash:** `7NsNN2WPDCCwd74j59sNlF1q5yW+GFFFOLVyB/WKZBc=`
  - Base64
  - 32 bytes

**Characteristics:**

- Memory-hard algorithm.
- Designed to resist GPU and ASIC brute forcing.
- Most secure of the supported formats.

> **Important**
>
> The **SCrypt** hash scheme is **not compatible with FIPS mode**. If your deployment requires FIPS compliance, don't enable SCrypt. Use PBKDF2 instead.

## Step 3: How Access Server chooses the hash format

Access Server selects the hashing algorithm based on:

- The version you're running.
- Whether your installation is **fresh** or **upgraded**.
- Whether you've explicitly enabled **SCrypt**.

> **Tip**
>
> You can't configure the hash scheme in `as.conf`. The only tunable option is enabling SCrypt with a `sacli` directive in supported versions.

### 3.1 Determine your version and install type

1. Check your [Access Server version](https://openvpn.net/as-docs/tutorials/tutorial--what-is-my-access-server-version.md).
2. Determine whether your system is:
   - An **older deployment** upgraded over time (for example, started on 2.10.0 or below and later upgraded), or
   - A **fresh install** created directly on 2.10.0 or later.

### 3.2 How hashing behaves by version

1. **Access Server 2.10.0 or earlier:**
   - All local user passwords use **SHA-256**.
2. **Access Server 2.10.1 or later**, and the system was **upgraded from 2.10.0 or earlier**:
   - Existing users keep their **SHA-256** hashes.
   - A user's hash is updated to **PBKDF2** when that user changes their password.
   - If you later enable **SCrypt** (see next section), and are on **2.11.0 or later**, a user's hash is updated to **SCrypt** instead when they change their password.
3. **Access Server 2.10.1 or later**, and this was a **fresh install**:
   - New local users use **PBKDF2** by default.
   - There's no way to change them back to **SHA-256**.
   - If you are on **2.11.0 or later** and enable SCrypt, users will migrate to **SCrypt** when their passwords are changed.

### 3.3 Enabling SCrypt (Access Server 2.11.0+)

1. If you want to use **SCrypt** for local passwords and you're running **Access Server 2.11.0 or later**, enable it with:

   ```
   cd /usr/local/openvpn_as/scripts
   ./sacli --key "auth.local.0.prefer_scrypt" --value "true" ConfigPut
   ./sacli start
   ```
2. After enabling SCrypt:
   - Existing users keep their current hash (SHA-256 or PBKDF2) until they change their password.
   - When a user changes their password, their `pvt_password_digest` is recalculated using **SCrypt**.

   > **Important**
   >
   > The **SCrypt** hash scheme is **not compatible with FIPS mode**. If your deployment requires FIPS compliance, don't enable SCrypt. Use PBKDF2 instead.

## Step 4: Tips for backward compatibility and migration

Access Server maintains backward compatibility with older hash formats, so users aren't locked out during upgrades. Hashes are only updated when a user changes their password.

1. Identify whether any users were created on earlier versions of Access Server.
   - Local user accounts originating on **2.10.0 or earlier** always created local passwords using **SHA-256**.
2. Understand how Access Server handles upgrades:
   - When upgrading from **2.10.0 or earlier to any new version**, existing users **keep their SHA-256 hashes**.
   - Access Server does **not** automatically convert old hashes to newer formats.
3. Know when hashes are updated:
   - A user's password is rehashed **only when they change it**.
   - The new hash format depends on your version and configuration:
     - **PBKDF2** becomes the new hash on password change when running **2.10.1+** (default behavior).
     - **SCrypt** becomes the new hash on password changes only when running **2.11.0 or later**, and `auth.local.0.prefer_scrypt` is enabled.
4. Use this behavior to strategically:
   - Prevent authentication failures after upgrades by allowing existing hashes to remain valid until users naturally change their passwords.
   - Gradually migrate users to modern hashing algorithms (PBKDF2 or SCrypt) without forcing immediate downtime.
5. If you want all users to migrate to PBKDF2 or SCrypt immediately:
   - Require a global password reset.
   - Communicate the change to users to avoid disruption.

---

Prev: [Tutorial: How to Change the Password for Your New Administrative Account](https://openvpn.net/as-docs/tutorials/tutorial--change-admin-user-password.md)
Next: [Tutorial: Configure the Authentication Failure Lockout Policy](https://openvpn.net/as-docs/tutorials/tutorial--authentication-failure-lockout-policy.md)
Index: https://openvpn.net/as-docs/llms.txt
