serverpod_auth_sms_crypto_server

pub package

Encrypted phone number storage implementation for Serverpod SMS authentication (server-side).

中文文档

💡 Recommended: Use the combined package serverpod_auth_sms instead of importing this package directly. The combined package handles Protocol/Endpoints conflicts automatically and includes comprehensive documentation.

Note: This package stores both hash and encrypted values, so it covers all functionality of serverpod_auth_sms_hash_server while also supporting phone number decryption.

Features

  • Reversible Encryption - Uses AES-256-GCM to encrypt phone numbers, safely decryptable
  • Dual Indexing - Stores both hash (for lookup) and encrypted value (for decryption)
  • Integrity Verification - GCM mode provides authenticated encryption, prevents tampering
  • Key Management - Supports secure key loading from configuration files

Use Cases

  • Business scenarios requiring original phone numbers (e.g., customer support, order notifications)
  • Scenarios displaying partial phone numbers to users (e.g., 138****1234)
  • Data analysis requiring phone number anonymization

Installation

Server:

# gen_server/pubspec.yaml
dependencies:
  serverpod_auth_sms_crypto_server: ^0.1.6
  serverpod_auth_sms_core_server: ^0.1.6

Client:

# gen_client/pubspec.yaml
dependencies:
  serverpod_auth_sms_crypto_client: ^0.1.6
  serverpod_auth_sms_core_client: ^0.2.0

Database Migration

After adding the dependency, create database migrations:

cd your_server_project
serverpod create-migration

Usage

1. Generate Encryption Key

# Generate 32-byte random key and Base64 encode
openssl rand -base64 32

2. Configure Secrets

Add to config/passwords.yaml:

shared:
  phoneHashPepper: 'your-phone-hash-pepper'
  phoneEncryptionKey: 'base64-encoded-32-byte-AES-key'

Important:

  • Keys cannot be changed once set
  • Keys must be kept strictly confidential; leakage allows decryption of all phone numbers
  • Consider using HSM or key management service to protect keys

3. Create Storage Instance

import 'package:serverpod_auth_sms_crypto_server/serverpod_auth_sms_crypto_server.dart'
    hide Protocol, Endpoints;  // Avoid naming conflicts

// Load from config file
final phoneIdStore = PhoneIdCryptoStore.fromPasswords(pod);

// Or create manually
final phoneIdStore = PhoneIdCryptoStore(
  pepper: 'your-hash-pepper',
  encryptionKeyBytes: base64Decode('your-base64-key'),
);

4. Retrieve Original Phone Number

// Get decrypted phone number by user ID
final phone = await phoneIdStore.getPhone(
  session,
  authUserId: userId,
);

Database Table

This module creates the following database table:

CREATE TABLE serverpod_auth_sms_phone_id_crypto (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid_v7(),
  authUserId UUID NOT NULL UNIQUE REFERENCES serverpod_auth_core_user(id) ON DELETE CASCADE,
  phoneHash TEXT NOT NULL UNIQUE,
  phoneEncrypted BYTEA NOT NULL,
  nonce BYTEA NOT NULL,
  mac BYTEA NOT NULL
);

Storage Format

Field Description
authUserId Associated user ID
phoneHash HMAC-SHA256 hash (for unique index)
phoneEncrypted AES-256-GCM encrypted phone ciphertext
nonce Encryption nonce (12 bytes)
mac Message Authentication Code (16 bytes)

Security Considerations

  1. Key Protection - Encryption key is the most critical security element
  2. Access Control - Restrict access to getPhone() method
  3. Audit Logging - Log all decryption operations for security audit
  4. Compliance - Ensure compliance with local data protection regulations

Comparison with Hash Storage

Feature Crypto Storage Hash Storage
Reversibility Decryptable Irreversible
Storage Space Larger Smaller
Functionality Can retrieve original Verification only
Key Dependency Needs encryption key Hash pepper only

License

MIT License