Showing posts with label HSM. Show all posts
Showing posts with label HSM. Show all posts

Simple HSM and OpenSC Based File Encryption Script System Using Derived Keys

This document describes a secure file encryption system that uses a Hardware Security Module (HSM) for key derivation. The system ensures that encryption keys are derived securely within the HSM and never stored permanently on disk.

Table of Contents

Overview

Why HSM-Based Encryption?

Traditional file encryption methods often expose encryption keys or passwords to the operating system in various ways:

  • Keys stored on disk (even if encrypted)
  • Keys loaded into OS memory
  • Keys accessible to system processes
  • Keys vulnerable to memory dumps
  • Keys potentially exposed through swap files
  • Keys that could be intercepted by malware

This HSM-based approach provides superior security by:

  1. Hardware Isolation: All key derivation operations happen inside the HSM's secure boundary
  2. Minimal Key Exposure: Keys are derived on-demand and stored only briefly in RAM-based temporary files
  3. PIN Protection: Physical possession of the HSM alone is insufficient; PIN authentication is required
  4. Tamper Resistance: HSM hardware is designed to resist physical attacks
  5. Secure Cleanup: Temporary key files are securely wiped using shred after use
  6. Process Isolation: Even if the host system is compromised, the HSM's internal operations remain secure

System Operation

The system consists of two main operations:

  1. File encryption with a unique key derived from a random salt
  2. File decryption using the same salt to derive the identical key

The system uses the HSM's SHA-256 mechanism to derive encryption keys, ensuring that key derivation happens within the secure hardware environment.

Components

System Requirements

This encryption system is designed and tested for Linux environments (tested on RHEL 9). While the core components (OpenSC, OpenSSL) are available on macOS, some adjustments might be needed for full compatibility:

  • Linux (primary platform)
    • Tested on RHEL 9
    • Should work on most modern Linux distributions
    • All components available through standard package managers
  • macOS (potentially compatible)
    • Requires OpenSC installation via Homebrew
    • May need path adjustments for PKCS#11 module
    • Limited testing available
  • Windows (untested)
    • OpenSC and OpenSSL are available for Windows
    • Would require significant path and script adjustments
    • Has not been tested by the author
    • Might work with Cygwin or WSL (Windows Subsystem for Linux)

Hardware Requirements

The code snippets shown below match the features of the following HSM tokens:

They can be purchased from either:

  • CardOMatic GmbH (Identiv uTrust 3xxx in various form factors):
    • USB Tokens (recommended for desktop usage):
      • SmartCard-HSM 4K USB-Token (Standard form factor)
      • SmartCard-HSM 4K Mini USB-Token (Compact form factor)
    • Card Formats:
      • SmartCard-HSM-4K-Dual-IF (Dual Interface)
      • SmartCard-HSM-4K-Mini-SIM
      • SmartCard-HSM-4K-Micro-SIM
    • Special Formats:
      • SmartCard-HSM 4K MicroSD Card (For mobile devices)
  • Nitrokey Shop (Nitrokey HSM 2)

All devices feature 4K storage and support the required cryptographic operations.

⚠️ Important Compatibility Note:

This encryption system specifically requires HSM capabilities that are NOT available in PIV-based smartcards (like YubiKey PIV devices). PIV smartcards:

  • Do not support direct hash operations within the device
  • Cannot perform arbitrary SHA-256 operations on input data
  • Lack the required key derivation mechanisms
  • Have limited storage for custom objects

Only true HSM devices (like SmartCard-HSM or Nitrokey HSM 2) provide the necessary cryptographic operations for this system to work. YubiHSM 2 may work as well, but that statement requires a proper validation.

Software Components

  1. OpenSC PKCS#11 module (/usr/lib64/pkcs11/opensc-pkcs11.so)
  2. aes_encrypt.sh - Encrypts files using HSM-derived keys (see the code snippets below)
  3. aes_decrypt.sh - Decrypts files using HSM-derived keys (see the code snippets below)

Security Features

  1. Hardware-Based Key Derivation
    • All key derivation happens inside the HSM
    • Uses HSM's SHA-256 mechanism
    • Requires HSM PIN authentication for both encryption and decryption
  2. Unique Keys Per File
    • Each encryption operation uses a new random 32-byte salt
    • Salt is used to derive a unique key through the HSM
    • Prevents key reuse across different files
  3. Secure Key Handling
    • Derived keys exist only in RAM-based temporary files during operations
    • Keys are securely wiped using shred after use
    • No keys are stored permanently on disk
  4. File Format
    • First 32 bytes: Random salt used for key derivation
    • Remaining bytes: AES-256 encrypted data (mode depends on implementation)
  5. Operational Security
    • HSM Redundancy: Maintain at least two HSM tokens with identical ECDSA key pairs
      • Critical for disaster recovery
      • Protects against HSM loss, theft, or hardware failure
      • Ensures access if one token gets locked out due to PIN attempts
      • Both tokens should be stored securely in different locations
    • Without a working HSM containing the correct key pair, decryption is impossible
    • Regular testing of backup HSM tokens is recommended
  6. HSM Cryptographic Capabilities

    You can inspect the HSM's supported mechanisms using:

    pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so --list-mechanisms

    Example output:

    Using slot 0 with a present token (0x0)
    Supported mechanisms:
      SHA-1, digest
      SHA224, digest
      SHA256, digest
      SHA384, digest
      SHA512, digest
      MD5, digest
      RIPEMD160, digest
      GOSTR3411, digest
      ECDSA, keySize={192,521}, hw, sign, verify, EC F_P, EC parameters, EC OID, EC uncompressed
      ECDSA-SHA384, keySize={192,521}, sign, verify
      ECDSA-SHA512, keySize={192,521}, sign, verify
      ECDSA-SHA1, keySize={192,521}, hw, sign, verify, EC F_P, EC parameters, EC OID, EC uncompressed
      ECDSA-SHA224, keySize={192,521}, hw, sign, verify, EC F_P, EC parameters, EC OID, EC uncompressed
      ECDSA-SHA256, keySize={192,521}, hw, sign, verify, EC F_P, EC parameters, EC OID, EC uncompressed
      ECDH1-COFACTOR-DERIVE, keySize={192,521}, hw, derive, EC F_P, EC parameters, EC OID, EC uncompressed
      ECDH1-DERIVE, keySize={192,521}, hw, derive, EC F_P, EC parameters, EC OID, EC uncompressed
      ECDSA-KEY-PAIR-GEN, keySize={192,521}, hw, generate_key_pair, EC F_P, EC parameters, EC OID, EC uncompressed
      RSA-X-509, keySize={1024,4096}, hw, decrypt, sign, verify
      RSA-PKCS, keySize={1024,4096}, hw, decrypt, sign, verify
      SHA1-RSA-PKCS, keySize={1024,4096}, sign, verify
      SHA224-RSA-PKCS, keySize={1024,4096}, sign, verify
      SHA256-RSA-PKCS, keySize={1024,4096}, sign, verify
      SHA384-RSA-PKCS, keySize={1024,4096}, sign, verify
      SHA512-RSA-PKCS, keySize={1024,4096}, sign, verify
      MD5-RSA-PKCS, keySize={1024,4096}, sign, verify
      RIPEMD160-RSA-PKCS, keySize={1024,4096}, sign, verify
      RSA-PKCS-PSS, keySize={1024,4096}, hw, sign, verify
      SHA1-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
      SHA224-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
      SHA256-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
      SHA384-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
      SHA512-RSA-PKCS-PSS, keySize={1024,4096}, sign, verify
      RSA-PKCS-OAEP, keySize={1024,4096}, hw, decrypt
      RSA-PKCS-KEY-PAIR-GEN, keySize={1024,4096}, generate_key_pair

    The HSM supports a comprehensive set of cryptographic operations:

    • Hash Functions:
      • SHA family (SHA-1, SHA224, SHA256, SHA384, SHA512)
      • MD5
      • RIPEMD160
      • GOSTR3411
    • ECDSA Operations (key sizes 192-521 bits):
      • Key pair generation
      • Signing/verification with various hash combinations
      • Hardware-accelerated operations
      • Support for standard curves (EC F_P)
    • RSA Operations (key sizes 1024-4096 bits):
      • Key pair generation
      • Encryption/decryption
      • Signing/verification with various hash combinations
      • Support for PKCS, PSS, and OAEP padding
    • Key Derivation:
      • ECDH1-DERIVE
      • ECDH1-COFACTOR-DERIVE

    This encryption system specifically uses the SHA256 mechanism for key derivation, ensuring the operation is performed securely within the HSM's hardware boundary.

HSM Object Inspection

To inspect the objects (keys, certificates, data) stored on your HSM, use the pkcs11-tool --list-objects command:

pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so --list-objects

Expected Output Format

The command will show all objects stored on your HSM. Here's an example output:

Using slot 0 with a present token (0x0)
Certificate Object; type = X.509 cert
  label:      vesso_ecdsa#ssh
  subject:    DN: CN=Test User
  serial:     65C25210C8EDD2269D3DFFB836C2485C0A17BC32
  ID:         01
  uri:        pkcs11:model=PKCS%2315%20emulated;manufacturer=www.CardContact.de;serial=DECC0900169;token=SmartCard-HSM%20%28UserPIN%29;id=%01;object=test_ecdsa%23ssh;type=cert

Public Key Object; EC  EC_POINT 384 bits
  EC_POINT:   046104644baa533af20667849c4a6f38092e663f376d167cc1f64adca5cda8b72b1998d7757ac9057695cec32d1fc6239f8a282c9a803cb603dc1dd81907e411e737ab8e69129ea97035895bce14cc079043848c890ef969b6330c8a65418904a9d414
  EC_PARAMS:  06052b81040022
  label:      test_ecdsa#ssh
  ID:         01
  Usage:      encrypt, verify
  Access:     local
  uri:        pkcs11:model=PKCS%2315%20emulated;manufacturer=www.CardContact.de;serial=DECC0900169;token=SmartCard-HSM%20%28UserPIN%29;id=%01;object=test_ecdsa%23ssh;type=public

Public Key Object; EC  EC_POINT 256 bits
  EC_POINT:   0441047bfd2ff666960d4186f1aab2370b138554fe2dc2163a7016e2967624b8ad1ee3e36d25c84cac28b9040cf80ff68fa63e06c73a44a21ef70a74701fa8ea30c3d4
  EC_PARAMS:  06082a8648ce3d030107
  label:      ECDH-KEY
  ID:         02
  Usage:      verify
  Access:     none
  uri:        pkcs11:model=PKCS%2315%20emulated;manufacturer=www.CardContact.de;serial=DECC0900169;token=SmartCard-HSM%20%28UserPIN%29;id=%02;object=ECDH-KEY;type=public

Public Key Object; EC  EC_POINT 256 bits
  EC_POINT:   044104e1dc094f873e00eb86626f7ae0a845885df08cb89a797d29271d6b7f602e685bf9681cda2ecaeaa671f39837a11ee9259142c706d988558db907ad6560879ac3
  EC_PARAMS:  06082a8648ce3d030107
  label:      ECDH-AES-Key
  ID:         03
  Usage:      verify
  Access:     none
  uri:        pkcs11:model=PKCS%2315%20emulated;manufacturer=www.CardContact.de;serial=DECC0900169;token=SmartCard-HSM%20%28UserPIN%29;id=%03;object=ECDH-AES-Key;type=public

Profile object 1385173136
  profile_id:          CKP_PUBLIC_CERTIFICATES_TOKEN (4)

Understanding the Output

  1. Object Types:
    • Certificate Object: X.509 certificates with subject and serial information
    • Public Key Object: Public keys with their parameters and points
    • Profile Object: HSM configuration profiles
  2. Object Attributes:
    • label: Name of the object (e.g., "test_ecdsa#ssh", "ECDH-KEY")
    • ID: Object identifier (01, 02, 03)
    • Usage: Object capabilities (encrypt, verify)
    • Access: Access restrictions (local, none)
    • uri: PKCS#11 URI identifying the object

Key Objects in This Setup

  • ID 01: SSH ECDSA key (384-bit) with certificate
  • ID 02: ECDH key (256-bit) for key exchange
  • ID 03: ECDH-AES key (256-bit) for encryption operations

Usage Notes

  1. If the HSM is locked, add --login and provide a PIN:
    pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so --login --list-objects
  2. Use this command to:
    • Verify key installation and parameters
    • Check certificate details
    • Audit HSM object configuration
    • Confirm key availability before operations

Implementation Details

Encryption Process

  1. Salt Generation
    openssl rand -out "$SALT_FILE" 32
  2. Key Derivation in HSM
    pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \ --slot 0 \ --login \ --pin "$HSM_PIN" \ --hash \ --mechanism SHA256 \ --input-file "$SALT_FILE" > "$KEY_FILE"
  3. File Encryption
    • Salt is written to the start of the output file
    • Data is encrypted using AES-256-CTR with the derived key
    cat "$SALT_FILE" > "$OUTPUT_FILE" openssl enc -aes-256-ctr -pbkdf2 -iter 1 -salt -in "$INPUT_FILE" -kfile "$KEY_FILE" >> "$OUTPUT_FILE"
  4. Secure Cleanup
    shred -u "$SALT_FILE" "$KEY_FILE"

Decryption Process

  1. Salt Extraction
    dd if="$INPUT_FILE" of="$SALT_FILE" bs=32 count=1 dd if="$INPUT_FILE" of="$ENCRYPTED_DATA" bs=1 skip=32
  2. Key Derivation in HSM
    • Uses the same HSM SHA-256 mechanism with the extracted salt
    • Produces identical key as encryption
  3. File Decryption
    openssl enc -aes-256-ctr -pbkdf2 -iter 1 -d -salt -in "$ENCRYPTED_DATA" -out "$OUTPUT_FILE" -kfile "$KEY_FILE"
  4. Secure Cleanup
    shred -u "$SALT_FILE" "$ENCRYPTED_DATA" "$KEY_FILE"

Important Note: Why --hash Instead of --derive

When implementing this encryption system, you might be tempted to use the --derive option with pkcs11-tool. However, this will result in an error:

pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so --derive --mechanism SHA256 --input-file salt.bin error: Private key not found Aborting.

Why --derive Doesn't Work

The --derive option in pkcs11-tool is designed for key derivation operations that require a private key, such as:

  • ECDH (Elliptic Curve Diffie-Hellman) key exchange
  • Key derivation using existing private keys
  • Cryptographic operations that need a base key

The --derive option expects:

  1. A private key to be specified (using --id, --label, or --object-index)
  2. A mechanism that supports key derivation (like ECDH1-DERIVE)
  3. Input data that will be used with the private key for derivation

Why --hash is Correct

For our encryption system, we want to perform a simple hash operation on the salt to create a key. This is exactly what the --hash option provides:

pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \ --slot 0 \ --login \ --pin "$HSM_PIN" \ --hash \ --mechanism SHA256 \ --input-file "$SALT_FILE" > final_key.bin

The --hash option:

  1. Takes input data (our salt)
  2. Performs the specified hash operation (SHA256) within the HSM
  3. Returns the hash result as output
  4. Doesn't require any private keys

HSM Private Keys vs Hash Operations

Your HSM contains several private keys (both RSA and EC), but these are for different purposes:

Private Keys with derive usage:

  • Used for ECDH key exchange operations
  • Require a corresponding public key for derivation
  • Used in protocols like TLS key exchange

Hash Operations:

  • Simple one-way functions
  • Don't require any keys
  • Perfect for our key derivation from salt

Verification

You can verify the available private keys and their capabilities:

# List private keys (requires PIN) pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so --login --list-objects --type privkey # Example output showing EC keys with derive capability: # Private Key Object; EC # label: test@example.com#59edd63 # ID: 02 # Usage: sign, derive # Access: sensitive, always sensitive, never extractable, local

The derive usage on EC keys is for ECDH operations, not for simple hashing. Our encryption system correctly uses --hash for the SHA-256 operation on the salt.

Hash Mechanism Flexibility

The encryption system is not limited to SHA-256. You can use any hash mechanism supported by your HSM, as long as it provides sufficient output length for your AES key. The choice of hash mechanism depends on your security requirements and HSM capabilities.

Available Hash Mechanisms

Based on the HSM mechanisms list shown earlier, your HSM supports these hash functions:

  • SHA-1 (160 bits) - Not recommended for new implementations
  • SHA224 (224 bits) - Adequate for AES-256
  • SHA256 (256 bits) - Recommended for AES-256
  • SHA384 (384 bits) - Excellent for AES-256, provides extra security margin
  • SHA512 (512 bits) - Maximum security, excellent for AES-256
  • MD5 (128 bits) - Not recommended, insufficient for AES-256
  • RIPEMD160 (160 bits) - Not recommended for new implementations

Recommended Hash Mechanisms

For AES-256 encryption, the following mechanisms are recommended in order of preference:

  1. SHA512 - Maximum security margin (512 bits → 256 bits)
  2. SHA384 - Excellent security margin (384 bits → 256 bits)
  3. SHA256 - Optimal fit (256 bits → 256 bits)
  4. SHA224 - Adequate but minimal margin (224 bits → 256 bits, will be padded)

Using Different Hash Mechanisms

To use a different hash mechanism, simply change the --mechanism parameter:

# Using SHA-512 (maximum security) pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \ --slot 0 \ --login \ --pin "$HSM_PIN" \ --hash \ --mechanism SHA512 \ --input-file "$SALT_FILE" > final_key.bin # Using SHA-384 (excellent security margin) pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \ --slot 0 \ --login \ --pin "$HSM_PIN" \ --hash \ --mechanism SHA384 \ --input-file "$SALT_FILE" > final_key.bin # Using SHA-224 (adequate but minimal margin) pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \ --slot 0 \ --login \ --pin "$HSM_PIN" \ --hash \ --mechanism SHA224 \ --input-file "$SALT_FILE" > final_key.bin

Security Considerations

  • SHA-512/SHA-384: Provide security margin beyond AES-256 requirements
  • SHA-256: Optimal fit for AES-256, widely trusted
  • SHA-224: Adequate but provides minimal security margin
  • SHA-1/MD5: Not recommended due to known vulnerabilities
  • RIPEMD160: Not recommended for new implementations

Implementation Note

When changing hash mechanisms, ensure that:

  1. Both encryption and decryption scripts use the same mechanism
  2. The mechanism is supported by your HSM (verify with --list-mechanisms)
  3. The output length is sufficient for your AES key size
  4. You maintain consistency across all encrypted files

Checking HSM Support

Always verify that your HSM supports the chosen mechanism:

pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so --list-mechanisms | grep -E "(SHA|MD5|RIPEMD)"

Cipher Mode Security

⚠️ Important Security Warning:

The original implementation uses AES-256-CBC mode, which has known vulnerabilities including padding oracle attacks and the need for proper IV handling. Modern applications should use more secure cipher modes.

Available Secure Cipher Modes

OpenSSL supports these secure AES-256 modes:

  • AES-256-CTR (Counter Mode) - Recommended for OpenSSL enc
    • No padding required
    • Resistant to padding oracle attacks
    • Stream cipher mode
    • Note: Does not provide authentication (use with caution)
  • AES-256-GCM (Galois/Counter Mode) - Best Security (if available)
    • Provides both encryption and authentication
    • No padding required
    • Built-in integrity protection
    • Resistant to padding oracle attacks
    • Note: Not supported by OpenSSL enc command in all versions
  • AES-256-CCM (Counter with CBC-MAC) - Good Alternative (if available)
    • Provides both encryption and authentication
    • No padding required
    • Built-in integrity protection
    • Slightly more complex than GCM
    • Note: Not supported by OpenSSL enc command in all versions
  • AES-256-CBC (Cipher Block Chaining) - Not Recommended
    • Vulnerable to padding oracle attacks
    • Requires proper IV handling
    • No built-in integrity protection
    • Only use if compatibility is absolutely required

Why Avoid CBC Mode?

CBC mode has several security issues:

  1. Padding Oracle Attacks: Attackers can exploit padding validation to decrypt data
  2. IV Requirements: Requires cryptographically secure random IVs
  3. No Integrity: Provides no protection against tampering
  4. Predictable Patterns: Can leak information about plaintext structure

Recommended Implementation

Use AES-256-CTR for compatibility with OpenSSL enc command:

# Encryption with CTR (recommended for OpenSSL enc) openssl enc -aes-256-ctr -pbkdf2 -iter 1 -salt -in "$INPUT_FILE" -kfile "$KEY_FILE" >> "$OUTPUT_FILE" # Decryption with CTR (recommended for OpenSSL enc) openssl enc -aes-256-ctr -pbkdf2 -iter 1 -d -salt -in "$ENCRYPTED_DATA" -out "$OUTPUT_FILE" -kfile "$KEY_FILE"

Note: If your OpenSSL version supports GCM/CCM in the enc command, use those modes instead for better security.

Alternative: CCM Mode

If your OpenSSL version supports CCM in the enc command:

# Encryption with CCM openssl enc -aes-256-ccm -pbkdf2 -iter 1 -salt -in "$INPUT_FILE" -kfile "$KEY_FILE" >> "$OUTPUT_FILE" # Decryption with CCM openssl enc -aes-256-ccm -pbkdf2 -iter 1 -d -salt -in "$ENCRYPTED_DATA" -out "$OUTPUT_FILE" -kfile "$KEY_FILE"

Alternative: GCM Mode

If your OpenSSL version supports GCM in the enc command:

# Encryption with GCM openssl enc -aes-256-gcm -pbkdf2 -iter 1 -salt -in "$INPUT_FILE" -kfile "$KEY_FILE" >> "$OUTPUT_FILE" # Decryption with GCM openssl enc -aes-256-gcm -pbkdf2 -iter 1 -d -salt -in "$ENCRYPTED_DATA" -out "$OUTPUT_FILE" -kfile "$KEY_FILE"

File Format with CTR/GCM/CCM

When using CTR, GCM, or CCM modes, the file format remains the same:

  • First 32 bytes: Random salt for key derivation
  • Remaining bytes: AES-256-CTR/GCM/CCM encrypted data

Compatibility Considerations

  • CTR: Compatible with OpenSSL enc command, no padding oracle attacks
  • GCM/CCM: Modern, secure, but not supported by OpenSSL enc command in all versions
  • CBC: Legacy compatibility only, avoid for new systems due to padding oracle attacks

Verification

Check available cipher modes on your system:

# Check what ciphers are supported by the enc command openssl enc -list | grep -E "(aes256)" # Check if GCM/CCM are available (they may not be supported by enc command) openssl list -cipher-algorithms | grep -E "(aes256-gcm|aes256-ccm)"

Usage

Setting Up the Scripts

Before using the encryption system, you need to create the encryption and decryption scripts. Copy the following code blocks and save them with the appropriate names:

1. Create the Encryption Script

Save the following content as aes_encrypt.sh:

#!/bin/bash
set -e

if [ "$#" -ne 1 ]; then
    echo "Usage: $0 "
    exit 1
fi

INPUT_FILE="$1"
OUTPUT_FILE="${INPUT_FILE}.enc"
SALT_FILE=$(mktemp)
KEY_FILE=$(mktemp -p /dev/shm)

# Configuration
SLOT=0

# Get HSM PIN
read -s -p "Enter HSM PIN: " HSM_PIN
echo

# Generate a random salt (32 bytes)
openssl rand -out "$SALT_FILE" 32

# Use HSM's SHA-256 to create key from salt
echo "Creating key in HSM..."
pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \
    --slot $SLOT \
    --login \
    --pin "$HSM_PIN" \
    --hash \
    --mechanism SHA256 \
    --input-file "$SALT_FILE" > "$KEY_FILE"

# Encrypt the file using the derived key from HSM
echo "Encrypting file..."
# Write salt at the start of the output file (we'll need it for decryption)
cat "$SALT_FILE" > "$OUTPUT_FILE"
# Encrypt the actual data using AES-256-CTR (more secure than CBC)
openssl enc -aes-256-ctr -pbkdf2 -iter 1 -salt -in "$INPUT_FILE" -kfile "$KEY_FILE" >> "$OUTPUT_FILE"

# Clean up
shred -u "$SALT_FILE" "$KEY_FILE"

echo "File encrypted successfully: $OUTPUT_FILE"

2. Create the Decryption Script

Save the following content as aes_decrypt.sh:

#!/bin/bash
set -e

if [ "$#" -ne 1 ]; then
    echo "Usage: $0 "
    exit 1
fi

INPUT_FILE="$1"
OUTPUT_FILE="${INPUT_FILE%.enc}.decrypted"
SALT_FILE=$(mktemp)
ENCRYPTED_DATA=$(mktemp)
KEY_FILE=$(mktemp -p /dev/shm)

# Configuration
SLOT=0

# Get HSM PIN
read -s -p "Enter HSM PIN: " HSM_PIN
echo

# Extract salt from encrypted file
dd if="$INPUT_FILE" of="$SALT_FILE" bs=32 count=1 2>/dev/null
dd if="$INPUT_FILE" of="$ENCRYPTED_DATA" bs=1 skip=32 2>/dev/null

# Use HSM's SHA-256 to create key from salt
echo "Creating key in HSM..."
pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \
    --slot $SLOT \
    --login \
    --pin "$HSM_PIN" \
    --hash \
    --mechanism SHA256 \
    --input-file "$SALT_FILE" > "$KEY_FILE"

# Decrypt the file using the derived key from HSM
echo "Decrypting file..."
openssl enc -aes-256-ctr -pbkdf2 -iter 1 -d -salt -in "$ENCRYPTED_DATA" -out "$OUTPUT_FILE" -kfile "$KEY_FILE"

# Clean up
shred -u "$SALT_FILE" "$ENCRYPTED_DATA" "$KEY_FILE"

echo "File decrypted successfully: $OUTPUT_FILE"

3. Make the Scripts Executable

After creating both files, make them executable:

chmod +x aes_encrypt.sh aes_decrypt.sh

Using the Scripts

Encrypting a File

./aes_encrypt.sh
  • Prompts for HSM PIN
  • Creates encrypted file with .enc extension
  • Original file remains unchanged

Decrypting a File

./aes_decrypt.sh
  • Prompts for HSM PIN
  • Creates decrypted file with .decrypted extension
  • Encrypted file remains unchanged

Security Considerations

  1. HSM PIN Protection
    • PIN is never stored in scripts
    • PIN is required for both encryption and decryption
    • Multiple incorrect PIN attempts may lock the HSM
  2. Temporary Files
    • All temporary files are securely wiped using shred
    • Includes salt files, key files, and intermediate data
  3. Key Handling Reality
    • Important: Derived keys are temporarily stored in secure temporary files
    • Keys are stored in regular temp files (not /dev/shm) for binary data compatibility
    • Keys are securely wiped using shred immediately after use
    • No keys are stored permanently on disk
    • The HSM's internal operations remain secure even if the host system is compromised
  4. Cold Boot Attack Mitigation
    • Enhanced: Keys are stored in regular temp files (not /dev/shm)
    • Keys are securely wiped using shred immediately after use
    • Temporary files are created in standard temp directories
    • Reduced exposure compared to /dev/shm storage
  5. Salt Management
    • Each file gets a unique random salt
    • Salt is stored with the encrypted data
    • 32 bytes of random data provides sufficient uniqueness

Limitations

  1. HSM must be available for both encryption and decryption operations
  2. HSM PIN must be known and HSM must be in an unlocked state
  3. System depends on the HSM's SHA-256 implementation
  4. No key rotation mechanism (each file is encrypted with its own unique key)
  5. Cold Boot Attack Mitigation: Keys are stored in RAM-based temp files (/dev/shm), reducing exposure

Cold Boot Attack Mitigation

Understanding the Threat

Cold boot attacks exploit the fact that RAM contents can persist for minutes to hours after power loss, especially in cold environments. Attackers with physical access can:

  1. Extract RAM contents after system shutdown
  2. Analyze memory dumps to find encryption keys
  3. Recover keys that were stored in /dev/shm files
  4. Decrypt files using recovered keys

Enhanced Implementation Security

The updated scripts store derived keys in regular temporary files (not /dev/shm), which:

  • ✅ Provides compatibility with binary data
  • ✅ Reduces cold boot attack exposure compared to /dev/shm
  • ✅ Keys are securely wiped using shred immediately after use
  • ✅ Uses standard temp directories instead of RAM-based filesystems

Mitigation Strategies

1. Current Implementation (Enhanced)

The scripts now use regular temporary files for binary data compatibility:

# Keys are stored in regular temp files (not /dev/shm) pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \ --slot $SLOT \ --login \ --pin "$HSM_PIN" \ --hash \ --mechanism SHA256 \ --input-file "$SALT_FILE" > "$KEY_FILE" # Use the key file directly openssl enc -aes-256-ctr -pbkdf2 -iter 1 -salt -in "$INPUT_FILE" -kfile "$KEY_FILE" >> "$OUTPUT_FILE"

2. Additional Security Enhancements

For even higher security, consider these additional measures:

#!/bin/bash
set -e

if [ "$#" -ne 1 ]; then
    echo "Usage: $0 "
    exit 1
fi

INPUT_FILE="$1"
OUTPUT_FILE="${INPUT_FILE}.enc"
SALT_FILE=$(mktemp)

# Configuration
SLOT=0

# Get HSM PIN
read -s -p "Enter HSM PIN: " HSM_PIN
echo

# Generate a random salt (32 bytes)
openssl rand -out "$SALT_FILE" 32

# Use HSM's SHA-256 to create key and use it directly
echo "Creating key in HSM..."
KEY_DATA=$(pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so \
    --slot $SLOT \
    --login \
    --pin "$HSM_PIN" \
    --hash \
    --mechanism SHA256 \
    --input-file "$SALT_FILE")

# Encrypt the file using the derived key directly
echo "Encrypting file..."
cat "$SALT_FILE" > "$OUTPUT_FILE"
echo "$KEY_DATA" | openssl enc -aes-256-ctr -pbkdf2 -iter 1 -salt -in "$INPUT_FILE" -kfile /dev/stdin >> "$OUTPUT_FILE"

# Clean up
shred -u "$SALT_FILE"

echo "File encrypted successfully: $OUTPUT_FILE"

3. System-Level Protections

Enable memory encryption:

# Check if memory encryption is available dmesg | grep -i "memory encryption\|mktme\|tme" # Enable secure boot and memory encryption in BIOS/UEFI # Use Intel TME (Total Memory Encryption) or AMD SME if available

Use encrypted swap:

# Ensure swap is encrypted swapon --show # If not encrypted, consider disabling swap for sensitive operations

4. Operational Security

Physical security measures:

  • Keep systems in secure locations
  • Use full-disk encryption
  • Implement proper shutdown procedures
  • Consider using secure enclaves (Intel SGX, AMD SEV)

Operational procedures:

  • Shut down systems immediately after sensitive operations
  • Use dedicated machines for encryption operations
  • Implement proper access controls
  • Regular security audits

Current Implementation

The scripts now implement enhanced security with binary data compatibility:

  1. Use regular temp files - Keys stored in standard temp directories (not /dev/shm)
  2. Binary data compatibility - Properly handles HSM binary output
  3. Secure cleanup - Keys wiped using shred immediately after use
  4. Reduced attack surface - No RAM-based filesystem storage

Security Trade-offs

Approach Cold Boot Risk Performance Complexity
Regular Temp Files (Current) Medium Fast Low
Memory Encryption Low Medium High
Dedicated Hardware Very Low Fast Very High

The current implementation provides a good balance of security and simplicity. For high-security environments, consider additional system-level protections like memory encryption.

Complete Implementation

The encryption system is implemented through two bash scripts that handle:

  1. Secure PIN input - Prompts for HSM PIN without displaying it
  2. Random salt generation - Creates unique 32-byte salts for each file
  3. HSM-based key derivation - Uses HSM's SHA-256 mechanism for key creation
  4. File encryption/decryption - Uses AES-256-CTR for secure encryption
  5. Secure cleanup - Wipes all temporary files using shred

The complete scripts are provided in the Usage section above, where you can copy them and save as aes_encrypt.sh and aes_decrypt.sh.

TODO List

Hardware Testing

  1. YubiHSM 2 FIPS Integration
    • Test compatibility with YubiHSM 2 FIPS
    • Verify SHA-256 mechanism availability and behavior
    • Test key derivation performance
    • Document any required modifications for YubiHSM 2 support
    • Test network sharing capabilities if relevant
    • Validate PKCS#11 module path and configuration
  2. Multiple Key Testing
    • Test behavior with multiple ECDSA keys
    • Verify key selection logic
    • Document needed modifications
    • Test key ID specification requirements

YubiHSM 2 and Cold Boot Attack Prevention

Overview

While the current system uses SmartCard-HSM devices for key derivation with host-based encryption, YubiHSM 2 offers a fundamentally different approach that can provide complete protection against cold boot attacks by performing all cryptographic operations within the HSM hardware itself.

YubiHSM 2 Hardware-Based Encryption

YubiHSM 2 supports direct AES encryption and decryption operations within the HSM hardware, available with firmware version 2.3.1 or later:

Supported Operations

  • AES-128/192/256 CBC Mode: encrypt-cbc and decrypt-cbc commands
  • AES-128/192/256 ECB Mode: encrypt-ecb and decrypt-ecb commands
  • Hardware-accelerated: All operations performed within the secure hardware boundary

Cold Boot Attack Prevention

This hardware-based approach provides complete protection against cold boot attacks:

  • Keys Never Leave the HSM: AES keys are stored and used entirely within the secure hardware
  • Encryption in Hardware: All cryptographic operations occur inside the HSM's secure boundary
  • No Host Memory Exposure: Plaintext and keys are never loaded into the host system's RAM
  • Hardware Isolation: Even if the host system is compromised, the HSM's internal operations remain secure
  • FIPS 140-2 Level 3: Certified tamper-resistant hardware with physical security protections

Implementation Differences

Current System (SmartCard-HSM)

# Key derivation in HSM, encryption on host pkcs11-tool --hash --mechanism SHA256 --input-file salt.bin > key.bin openssl enc -aes-256-ctr -kfile key.bin -in file.txt -out file.enc

YubiHSM 2 Approach

# Generate AES key in HSM yubihsm-shell -a generate-symmetric-key -l "file-key" -d 1 -c encrypt-cbc,decrypt-cbc -A aes256 # Encrypt data directly in HSM (chunked) yubihsm-shell -a encrypt-cbc -i -s -i data=

Data Size Limitations

Important Constraint: YubiHSM 2 has a maximum data size of approximately 2021 bytes per operation. This means:

  • Small files: Can be encrypted entirely within the HSM
  • Large files: Must be processed in ~2KB chunks
  • ⚠️ Performance impact: Chunked processing adds complexity and latency

Security Comparison

Aspect Current System (SmartCard-HSM) YubiHSM 2
Key Derivation ✅ HSM-based SHA-256 ✅ HSM-based SHA-256
Key Storage ✅ Hardware protected ✅ Hardware protected
File Encryption ❌ Host-based (OpenSSL) ✅ Hardware-based (limited size)
Cold Boot Protection ⚠️ Partial (keys briefly in temp files) ✅ Complete (all operations in HSM)
Large File Support ✅ Full support ❌ Limited to ~2KB chunks
Implementation Complexity ✅ Simple ❌ Complex (chunking required)

Practical Considerations

Advantages of YubiHSM 2

  • Complete cold boot attack prevention
  • All cryptographic operations in hardware
  • No key exposure to host memory
  • FIPS 140-2 Level 3 certification
  • Superior security model

Disadvantages of YubiHSM 2

  • Limited to ~2KB chunks per operation
  • More complex implementation for large files
  • Higher latency due to chunked processing
  • Requires custom chunking logic
  • Not suitable for streaming encryption

Recommendation

For environments where cold boot attacks are the primary security concern, YubiHSM 2 provides superior protection by keeping all cryptographic operations within the secure hardware boundary. However, the current SmartCard-HSM approach offers a better balance of security and practicality for general file encryption use cases.

Choose YubiHSM 2 if:

  • Cold boot attacks are your primary threat model
  • You can accept the complexity of chunked processing
  • You're working with smaller files or can implement chunking
  • You require FIPS 140-2 Level 3 compliance

Choose SmartCard-HSM if:

  • You need simple, practical file encryption
  • You work with large files frequently
  • You want straightforward implementation
  • You accept the minimal cold boot attack exposure of temporary key storage

Dependencies

  • OpenSC PKCS#11 module
  • OpenSSL for AES encryption and random number generation
  • Standard Unix tools (dd, cat, shred)
  • Bash shell

For more detailed instructions about SmartCard-HSM initialization and key generation, refer to SmartCard-HSM USB Token Setup Guide.

Usage Notes

  1. If the HSM is locked, add --login and provide a PIN:
    pkcs11-tool --module /usr/lib64/pkcs11/opensc-pkcs11.so --login --list-objects
  2. Use this command to:
    • Verify key installation and parameters
    • Check certificate details
    • Audit HSM object configuration
    • Confirm key availability before operations

What to do when an HSM token with a large number of stored certificates (or more than one HSM tokens are connected) prevents the SSH agent from using the correct key for SSH authentication on Linux

Many advanced Linux users have been struggling to get rid of one quite annoying situation - the interference between multiple HSM tokens connected to one system. Think about the situation when one token is only needed for SSH authentication and the other token is only needed for S/MIME and web authentication. If each of the tokens contains only one X.509v3 certificate and its private key, things should be fine and in that particular case the command line:

ssh-add -s /usr/lib64/opensc-pkcs11.so

will connect only two of the keys to the SSH agent.

But what if the HSM token hosts four certificates or more than one HSM token is services by the same PKCS#11 library? In that case, during the SSH authentication process, the SSH agent will try the available private keys one after another until the server accepts any of the keys as the proper authentication token. If you have too many keys in the HSM token, the ssh client will be involved in too many authentication attempts, and as a result, the SSH server will terminate the user's authentication. Of course, the latter also depends on the SSH server-side configuration, but the defaults are not in favour of executing multiple key tests.

How to solve this issue?

First, let's start with brining forward the bad news - there exists no definitive resolution in all instances. A workaround is only available. The workaround is not something compex - simply attach the HSM token that contains the key used for SSH authentication before the other HSM tokens, and execute:

ssh-add -s /usr/lib64/opensc-pkcs11.so

Afterwards, you may add as many HSM tokens as you wish to the Linux system. But only the first hinted HSM token will be used to operate with the SSH agent.

Now some details and more information about the process of using HSM tokens for authentication/signing. Read the information below if you are interested in those details.

The X.509v3 certificates get installed inside the HSM protected memory slots along with their private keys. To help the application with the access to that slots, a dedicated PKCS#11 module (library) is needed. In most cases, we employ the PKCS#11 module as a low-level backend in both direction. First, we transfer each X.509v3 certificate along with its private key to the protected memory inside the HMS token, reading that information from PKCS#12 files. Once the keys are stored inside the protected memory of the HSM token, we employ the PKCS#11 module to point the applications to the location of the installed private keys. Note that the applications never obtain direct access to the private keys. Instead, they send some computed hash to the crypto processor inside the HSM token, asking it to sign (encrypt) that hash with a private key with a certain ID (PKCS#12 module communicates those IDs to the application in advance).

Storing multiple keys inside HSM tokens always depends on the token model itself. Some tokens allow the use of multiple slots for signing and authentication, while some do not. The link below shows a good example of tokens that can store multiple X.509v3 certificates in their protected memory:

https://www.cardomatic.de/c/smartcard-hsm

Those brand of tokens can be programmed by using Smart Card Shell 3.

Even though the Yubico PIV tokens are popular, they cannot store multiple X.509v3 certificates and their corresponding private keys. While it is true that those PIV devices come with four slots, each slot has a different purpose, and only one of them can be employed for authentication. Which does not mean Yubico PIV tokens are not as good as the others. They just cannot store more than one certificate/key per dedicated slot. You may try to examine that by running the YubiKey Manager (Ykman) - it shows the four slots and reveals their purpose.

Regardless of the HSM management application, installation of X.509v3 certificates into the HSM tokens does not bring therein the corresponding certificate chains (even if those chains are stored in the original PKCS#12 blocks). The S/MIME client or browser that uses HSM tokens for signing or authentication is responsible for bringing the missing chain certificates into the signing or authentication process. Certificates included in chains are usually installed into special local files accessible and manageable by processing software cryptographic storage. Different programs rely on different file backends for saving and accessing the certificates needed to finish the chains when asked. For instance, Firefox, regardless of the OS environment, always employs Mozilla's NSS Shared DB files for that purpose. While running on Linux, Brave and Chrome for Linux also rely on Mozilla's NSS Shared DB. However, in the event that they are running on Windows, the Windows Certificate Store is utilized as a means of searching for certificates to complete the chain.

If you possess an HSM token that contains more than three X.509v3 certificates installed and accessible through PKCS#11 library, it is not recommended to use that token for SSH authentication. That advice is based on the way the ssh client utilizes the private keys during the authentication process.

What is the good practice to follow when preparing an HSM token, which will be used for SSH authentication only? Store only one certificate, which should be self-signed one. That self-signed X.509v3 certificate must be based on the originally generated SSH key pair stored under the ~/.ssh folder, and should be created and then inserted into the HSM token based on a PKCS#12 file. To create the self-signed certificate, simply run the command line:

openssl req -sha384 -x509 -key ~/.ssh/id_ecdsa -out ~/vesso@ssh-ecdsa.crt -subj "/CN=vesso@ssh-ecdsa" -days 3650

The self-signed certificate will be stored in ~/vesso@ssh-ecdsa.crt. Then compiose the PKCS#12 file:

openssl pkcs12 -export -legacy -key ~/.ssh/id_ecdsa -in ~/vesso@ssh-ecdsa.crt -name "vesso@ssh-ecdsa" -out vesso@ssh-ecdsa.p12

If you want to store that certificate and its private key onto your HSM key, use the appropriate device manager to import the content of the PKCS#12 file into the protected memory of the HSM token. If that is one of the HSM tokens mentioned above, adopt Smart Card Shell 3 for the import. In case you would like to use Yubico PIV token, then rely on the Yukman.

What to do if Smart Card Shell (scsh) cannot detect HSM tokens connected to RHEL9 or Rocky 9 installation

The HSM management through scsh on RHEL9 (incl Rocky 9) may pose a challenge due to an issue with the manner in which that Linux distribution installs PCSC Lite components. Consequently, neither the scsh command line tool nor scsh3gui are capable of recognizing the HSM tokens that have already been connected to the system.

The problem is caused by the set of libraries that are installed by default when smart card support is enabled on the distribution through the package system. That support implies the installation of libpcsclite.so.1 instead of libpcsclite.so. To make scsh recognize the connected HSM tokens, one should find a way to bring libpcsclite.so into the system, which is required by Java OpenJDK for successful execution of scsh classes.

Now, in greater details. By enabling smart card support, the package management system installs those two packages:

pcsc-lite
pcsc-lite-libs

as well as their dependencies. Here pcsc-lite-libs only provides:

/usr/lib64/libpcsclite.so.1

None of the above provides:

/usr/lib64/libpcsclite.so

At this juncture, it is advised to refrain from creating manually libpcsclite.so as a symlink to libpcsclite.so.1, as it may result in interference with the package system. There is a much more proper way to bring libpcsclite.so to the system:

dnf install pcsc-lite-devel

Installing pcsc-lite-devel just creates the necessary symlink and registers it in the RPM database.

SmartCard-HSM USB token: Using Smart Card Shell 3 for initializing and configuring the token, generating key pairs, and importing keys and X.509 certificates from external PKCS#12 containers

Content:

  1. Introduction
  2. Prerequisites
  3. Downloading and installing Smart Card Shell 3
  4. Running Smart Card Shell 3 GUI
  5. Loading the key manager in Smart Card Shell 3 GUI
  6. Initializing the token and configuring DKEK to enable the import of keys and X.509 certificates from PKCS#12 files
  7. Generating ECC key pair (by means of DKEK shares)
  8. Importing key pair and the corresponding X.509 certificate from PKCS#12 file into the token (by means of DKEK shares)

 

1. Introduction

The SmardCard-HSM (Standard-A USB) token (you can order it online):

is a reliable, fast, secure, and OpenSC compatible HSM device, for generating, storing, and importing RSA, AES, and Elliptic Curve (EC) keys and X.509 certificates. Maybe, the best feature of the device is its enhanced support for EC (up to 521-bit keys), and the ability to import key pairs and certificates from PKCS#12 containers. Later allows to clone a key pair into several token devices, as a hardware backup scenario.

Unfortunately, the vendor does not provide (yet) a comprehensive documentation for end users, describing in details the specific process of importing key pairs and X.509 certificates from PKCS#12 containers (files) into the token (which is something very much in demand). Therefore, the goal of this document is to fix (at least partially) that gap in the documentation.

Note, that the procedures, described above, are not part of the everyday practice. They are required only for initializing the token device, generating EC keys for curves that are not currently listed as supported in the token's firmware (for instance, secp384r1 curve is supported by the token's processor, but not listed as supported in the firmware and the OpenSC based tools cannot request secp384r1 key generation), and to import key pairs and X.509 certificates from PKCS#12 files.

 

2. Prerequisites

To be able to follow the steps given below, you need to have installed and updated Linux distribution, running a Graphical Desktop environment (GNOME, KDE). Recent OpenJDK (17 is recommended if available) must be installed and kept updated. Do not install OpenJDK manually, since it is an essential software package! Always use the package manager, provided by the vendor of your Linux distribution to install or update OpenJDK:

  • RHEL7, CentOS 7, Scientific Linux 7:

    # yum install java-11-openjdk.x86_64
  • Fedora (current), RHEL8/9, CentOS 8, Scientific Linux 8, Rocky Linux 8/9, Alma Linux 9:

    # dnf install java-17-openjdk.x86_64
  • Ubuntu:

    # apt-get install openjdk-17-jdk-headless

It is not a good idea to configure the HSM token and manage its content on a system, that is used for social networking, software testing, gaming, or any other activity, that might be considered risky in this case. Always use a dedicated desktop system (or dedicated Linux virtual machine) for managing your PKI infrastructure.

You might have more than one version of OpenJDK installed on your system. So the first step is to check that and set the latest OpenJDK as a default Java provider. Execute the following command line (be super user or root):

# alternatives --config java

to check how many Java packages (provides) are installed and available locally, and which one of them is set as current default. For example, the following result:

There are 2 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
*+ 1           java-11-openjdk.x86_64 (/usr/lib/jvm/java-11-openjdk-11.0.19.0.7-1.el9_1.x86_64/bin/java)
   2           java-17-openjdk.x86_64 (/usr/lib/jvm/java-17-openjdk-17.0.7.0.7-1.el9_1.x86_64/bin/java)


Enter to keep the current selection[+], or type selection number:

means there are two OpenJDK packages installed, and the first one is set a default Java provider (see which is the entry marked with "+" in the first column). To set OpenJDK 17 default Java provider, type the ID number assigned to the package in the list (in the "Selection" column) and press "Enter" afterwards (in the above example, the ID used is 2):

Enter to keep the current selection[+], or type selection number: 2

It is always a good idea to check if the symlinks created by the alternatives tool points to the correct target. The simplest way to do so for OpenJDK 11 is to follow the symlink /etc/alternatives/java:

$ ls -al /etc/alternatives/java

and verify that the target is the OpenJDK 11 java executable:

lrwxrwxrwx. 1 root root 63 Apr 29 13:58 /etc/alternatives/java -> /usr/lib/jvm/java-17-openjdk-17.0.7.0.7-1.el9_1.x86_64/bin/java

Also check if the Java major version of the target:

$ java --version

is 17:

openjdk 17.0.7 2023-04-18 LTS
OpenJDK Runtime Environment (Red_Hat-17.0.7.0.7-1.el9_1) (build 17.0.7+7-LTS)
OpenJDK 64-Bit Server VM (Red_Hat-17.0.7.0.7-1.el9_1) (build 17.0.7+7-LTS, mixed mode, sharing)

Also, have pcscd running.

 

3. Downloading and installing Smart Card Shell 3

Be sure you have OpenJDK 17 installed, as specified above. Then visit the web page:

https://www.openscdp.org/scsh3/download.html

click on "IzPack Installer" link, and save locally the provided JAR archive of the installer.

Decide what kind of installation of Smart Card Shell 3 do you really need - to allow all users of the system to run the program code (run the installer as super user), or to limit that ability to a certain unprivileged user (perform the installation using that particular user ID):

  • run the installer as super user (root):

    You should install the program into a system folder, where the users can only read and execute the Java code (no write access should be given by default). That kind of restrictions will protect the executable code from deletion of modification.

  • run the installer as a non-privileged user:

    In this case, the simplest solution is to install the program into the home folder of the user. That type of installation is recommended only for a user, who really understands how to keep the executable code safe.

If followed, the steps given bellow will install the executable code of the program in the home folder of those user, who is executing the installer.

Open a terminal and type:

$ java -jar /path/to/scsh3.XX.YYY.jar

(here XX and YYY are numbers, unique for the current version). The following window will appear (press there the button "Next" to continue):

Select the installation folder (use the button "Browse" to change it, if you do not like the one suggested by the installer), and press "Next":

Now you will be able to see the progress of the installation process (press the button "Next" to continue, when it is done):

Next, you need to decide whether or not to create a shortcut to the program in the GNOME "Applications" menu (it is recommended to create such a shortcut), and who will be able to invoke the installed program (the last is useful only if you install the software as super user or root into a system folder). Press the button "Next":

and in the last window of the installer, press "Done" to exit:

Important note for those who are running Smart Card Shell 3 on RHEL9 (Rocky Linux 9, Alma Linux 9)!

Smart Card Shell 3 needs the library libpcsclite.so, but no package provides libpcsclite.so on RHEL9. To overcome that issue, install the package pcsc-lite-libs (if it is not already installed) and create the symlink /usr/lib64/libpcsclite.so that points to /usr/lib64/libpcsclite.so.1:

cd /usr/lib64
ln -s libpcsclite.so.1 libpcsclite.so

 

4. Running Smart Card Shell 3 GUI

Be sure the Smart Card Shell 3 GUI is installed. Expand the "Applications" menu (1), go to "Programming" (2), press there "Smart Card Shell 3" (3):

and wait for the appearance of the main window of the program:

During the first run, a new window might appear, asking for configuring the path to a working directory, where the output files will be stored by default. Click the "Browse" button:

select the folder (1) and press "Open" (2) to go back:

Thus path to the folder will appear in the text field (next to the "Browse" button). In addition, mark at least "Use this as the default and do not ask again", to complete the configuration and pressing "OK" to exit:

 

5. Loading the key manager in Smart Card Shell 3 GUI

Run Smart Card Shell 3 GUI. The key manager is a loadable script, dedicated to manage the objects in the token.

To load it, either expand "File" menu and select there "Key Manager":

or press "Ctrl+M". Once loaded, the key manager will check if the token is connected and will create in the main window a tree of those objects, it discovered in the token. Details about all important events will be reported in the "Shell" tab:

 

6. Initializing the token and configuring DKEK to enable the import of keys and X.509 certificates from PKCS#12 files

The goal of the initialization process, is to enable the import (export too) of keys and X.509 certificates, stored in files (most often PKCS#12 files), into the token, , based on "device-key-encryption-key" (DKEK) type of store. Note that DKEK is not enabled by default.

WARNING! DURING THE INITIALIZATION, ALL DATA, STORED IN THE TOKEN, WILL BE LOST!

To start with the initialization, run the Smart Card Shell 3, load the key manager script, click once with the right button of the mouse upon "SmartCard-HSM" (that is the root of the key manager tree), and select "Initialize Device" in the menu:

Supply the following information (or press "Cancel" to terminate the initialization):

  • The actual SO-PIN for configuring the token. The default SO-PIN code is 3537363231383830, unless it has been changed (if you forget the SO-PIN, consider the token lost). Press "OK" to continue:

  • The label of the token (that is the token's friendly name, displayed in the PKI applications). Press "OK" to continue:

  • The authentication mechanism for restricting the access to the objects and processor of the token. In most cases, you might need to select "User PIN" (you may set another authentication mechanism, but this one is the most poplar one). Press "OK" to continue:

  • The way to restore the access to the keys and X.509 certificates, if the PIN is lost, forgotten, or locked (if a wrong PIN is entered more than 3 times, consecutively). Select "Resetting PIN with SO-PIN allowed" and press "OK" (select "Resetting PIN with SO-PIN not allowed" only in specific cases, where the implementation of such policy is necessary):

  • The new PIN code (do not use the number shown in the picture bellow). Press "OK" to continue:

  • The new PIN code (again, for confirmation). Press "OK" to continue:

  • Request for using "DKEK Shares". Press "OK" to continue:

  • The number of DKEK shares (use 1, unless you are expert). Press "OK" to continue:

  • Press "Cancel" here (if you press "OK" both SO-PIN and PIN codes will be stored locally in an unencrypted file):

After the success of the initialization, you will see only three objects displayed in the key manager tree: User PIN, SO-PIN, and DKEK entry. The message "Initializing complete" (an indication that the requested initialization has been successfully completed) will be seen in the "Shell" tab:

Note, that at this point, the requested DKEK shares are not yet initialized or/and imported to the token! The appearance of "DKEK set-up in progress with 1 of 1 shares missing" in the key manager tree indicates that. You need to request manually the creation of DKEK shares file and import its content to the token, by following strictly the instructions given bellow:

  • Request the creation of DKEK share, by clicking once with the right button of the mouse on the root of the key manager tree (on "SmartCard-HSM) and picking "Create DKEK share" in the menu:

  • Enter the name of DKEK file to create, and press "OK" (store the file in the working directory of the program, configured during the first run):

  • Set the password for protecting the DKEK share file content and press "OK":

  • Confirm the password for protecting the DKEK share file content and press "OK":

  • With the left button of the mouse, click once upon the object named "DKEK set-up in progress with 1 of 1 shares missing", displayed in the key manager section of the main window of the program:

  • Use the button "Browse" to find and choose the created DKEK file (file extension is *.pbe), and press "OK":

  • Enter the password set (before) for protecting the content of the DKEK file:

It will take up to 10 seconds to derive the keys and import the DKEK into the token (watch the related messages, appearing in the "Shell" tab). At the end, you will see that the object "DKEK set-up in progress with 1 of 1 shares missing" (in the key manager tree) will be renamed (the new name will include the ID of the DKEK object):

IMPORTANT! At this point, you need to store a copy of the DKEK share file, generated during the initialization, in a safe place!

In the examples above, that file is /home/vesso/CardContact/2019_02.pdb, but in you case the file will be with different name and location.

 

7. Generating ECC key pair (by means of DKEK shares)

IMPORTANT! Be absolutely sure that no application, other than Smart Card Shell 3, is communicating with the token. Stop all running processes of PKCS#11 compatible software (like Mozilla Firefox, Mozilla Thunderbird, Google Chrome, XCA), that might take over the token.

Start the Smart Card Shell 3, plug the token into the USB port, and load the key manager script. Be sure that the token is initialized properly, to support DKEK shares.

Click once on the token name, in the key manager section, with the right button of the mouse and select "Generate ECC Key" in the menu:

Select the elliptic curve type, and press "OK":

Provide a friendly name (alias) for the key pair (it is an internal name for naming the key pair object in the token) and press "OK":

Type (separated by comma) the list of the hex codes of the signature algorithms, that will be allowed for the signing, when using the encryption key (the most commonly used ones, 73,74,75, are given in the example bellow), then press "OK":

Wait until the token is finishing with the generation of the requested key pair. Once ready, you will see the new key object under the tree of the DKEK share:

 

7. Importing key pair and the corresponding X.509 certificate from PKCS#12 file into the token (by means of DKEK shares)

IMPORTANT! Be absolutely sure that no application, other than Smart Card Shell 3, is communicating with the token. Stop all running processes of PKCS#11 compatible software (like Mozilla Firefox, Mozilla Thunderbird, Google Chrome, XCA), that might take over the token.

Otherwise the PKCS#12 import might fail, by rising (in the "Shell" tab) the following error:

GPError: Card (CARD_INVALID_SW/27010) - "Unexpected SW1/SW2=6982 (Checking error: Security condition not satisfied) received" in ...

Start the Smart Card Shell 3, plug the token into the USB port, and load the key manager script. Be sure that the token is initialized properly, to support DKEK shares. Using DKEK share in this case is mandatory for this operation.

  • Click once on the token name in the key manager section, with the right button of the mouse, and select "Import from PKCS#12" in the menu:

  • Specify the number of DKEK shares to use (use 1, if you follow the recipes provided in this document), and click "OK":

  • Select the file, containing the DKEK shares (use the file name created during the initialization), and click "OK":

  • Enter the password for decrypting the DKEK file (that password is set during the creation of the file), click "OK", and wait up to 10 seconds for generating the shared keys:

  • Select the PKCS#12 file and click "OK":

  • Provide the password, set for protecting the content of the PKCS#12 file, and click "OK":

  • Select the key pair and X.509 certificate to import from the PKCS#12 file, by choosing their internal PKCS#12 name, and click "OK":

  • Enter a name to assign to the imported key pair and X.509 certificate, and click "OK":

  • Click "OK" if you wanna import more key pairs and X.509 certificates, stored in the same PKCS#12 file, or click "Cancel" to finish:

If the import is successful, you will see the key pair imported into the DKEK share (in the key manager section), and information about the process, in the "Shell" section (as shown in the red frames bellow):

IMPORTANT! You cannot import X.509 certificate chain from a PKCS#12 container into the token, by using the procedure proposed above.

But you might do that later, by using pkcs11-tool, it that is really necessary. Notice, that the X.509 certificates in the chain are public information and they might be used in out-of-the-box manner (installed in the software certificate repository of the browser, which will be using with the token). Their presence in the token storage is not mandatory.


Creative Commons - Attribution 2.5 Generic. Powered by Blogger.

Implementing LUKS Encryption on Software RAID Arrays with LVM2 Management

A comprehensive guide to partition-level encryption for maximum security ...

Search This Blog

Translate