security

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 24, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package security provides PDF encryption and security features.

This file implements AES encryption for PDF documents (PDF 1.5+).

Supported AES encryption:

  • AES-128 with 128-bit keys (PDF 1.5 compatible, V=4, CFM=/AESV2)
  • AES-256 with 256-bit keys (PDF 1.7 Extension Level 3, V=5, CFM=/AESV3)

AES encryption in PDF uses:

  • CBC (Cipher Block Chaining) mode
  • PKCS#7 padding
  • Random initialization vector (IV) prepended to encrypted data

Package security provides PDF encryption and security features.

This file implements PDF decryption for reading encrypted PDF documents.

Supported decryption:

  • RC4 with 40-bit keys (V=1, R=2)
  • RC4 with 128-bit keys (V=2, R=3)
  • AES-128 with 128-bit keys (V=4, R=4, CFM=AESV2)

The decryption follows the PDF Standard Security Handler algorithms as specified in PDF Reference 1.7, Section 3.5.

Package security provides PDF encryption and security features.

This package implements the PDF Standard Security Handler (Algorithm 2.A) as specified in PDF Reference 1.7, Section 3.5.

Supported encryption algorithms:

  • RC4 with 40-bit keys (PDF 1.1 compatible)
  • RC4 with 128-bit keys (PDF 1.4 compatible)

The package handles:

  • User password (opens document with restrictions)
  • Owner password (opens document with full access)
  • Permission flags (print, copy, modify, etc.)

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrMissingFileID is returned when FileID is not provided for encryption.
	ErrMissingFileID = errors.New("file ID is required for encryption")

	// ErrInvalidKeyLength is returned when an unsupported key length is used.
	ErrInvalidKeyLength = errors.New("key length must be 40, 128, or 256 bits")

	// ErrInvalidPassword is returned when password verification fails.
	ErrInvalidPassword = errors.New("invalid password")

	// ErrPasswordRequired is returned when a password is needed to open an encrypted PDF.
	ErrPasswordRequired = errors.New("password required for encrypted PDF")

	// ErrUnsupportedVersion is returned when encryption version is not supported.
	ErrUnsupportedVersion = errors.New("unsupported encryption version")

	// ErrInvalidPadding is returned when PKCS#7 padding is invalid.
	ErrInvalidPadding = errors.New("invalid PKCS#7 padding")

	// ErrDataTooShort is returned when encrypted data is shorter than expected.
	ErrDataTooShort = errors.New("encrypted data too short")
)

Functions

This section is empty.

Types

type AESEncryptor

type AESEncryptor struct {
	// contains filtered or unexported fields
}

AESEncryptor handles AES encryption/decryption for PDF objects.

AES encryption is more secure than RC4 and is recommended for new PDFs. It uses CBC mode with PKCS#7 padding and random initialization vectors.

func NewAESEncryptor

func NewAESEncryptor(config *EncryptionConfig) (*AESEncryptor, error)

NewAESEncryptor creates a new AES encryptor with the given configuration.

Supported key lengths:

  • 128 bits (16 bytes) for AES-128 (PDF 1.5+)
  • 256 bits (32 bytes) for AES-256 (PDF 1.7 Extension Level 3+)

Example:

config := &EncryptionConfig{
    UserPassword:  "userpass",
    OwnerPassword: "ownerpass",
    Permissions:   PermissionPrint | PermissionCopy,
    KeyLength:     128, // or 256 for AES-256
    FileID:        "document-file-id",
}
enc, err := NewAESEncryptor(config)

func (*AESEncryptor) DecryptData

func (e *AESEncryptor) DecryptData(data []byte) ([]byte, error)

DecryptData decrypts AES-encrypted data.

The data must be in the format: [IV (16 bytes)][encrypted data]. PKCS#7 padding is removed after decryption.

func (*AESEncryptor) EncryptData

func (e *AESEncryptor) EncryptData(data []byte) ([]byte, error)

EncryptData encrypts data using AES with a random IV.

The IV is prepended to the encrypted data as required by PDF spec.

Example:

encrypted, err := enc.EncryptData([]byte("Hello, World!"))
// Result: [16-byte IV][encrypted data with PKCS#7 padding]

func (*AESEncryptor) GetEncryptionDict

func (e *AESEncryptor) GetEncryptionDict() *EncryptionDict

GetEncryptionDict returns the encryption dictionary.

type Decryptor added in v0.6.0

type Decryptor interface {
	// DecryptStream decrypts stream data for the given object.
	DecryptStream(data []byte, objNum, genNum int) ([]byte, error)

	// DecryptString decrypts a string value for the given object.
	DecryptString(data []byte, objNum, genNum int) ([]byte, error)
}

Decryptor decrypts PDF streams and strings on a per-object basis.

Each PDF object is encrypted with a unique key derived from the document encryption key and the object/generation numbers.

func NewDecryptor added in v0.6.0

func NewDecryptor(info *EncryptionInfo, password string) (Decryptor, error)

NewDecryptor verifies the password against the encryption info and returns an appropriate Decryptor implementation.

For V=1/2 (RC4), it returns an rc4Decryptor. For V=4 with CFM=AESV2 (AES-128), it returns an aes128Decryptor. For V=5 (AES-256), it returns ErrUnsupportedVersion.

Returns ErrPasswordRequired if the password does not match.

type EncryptionConfig

type EncryptionConfig struct {
	// UserPassword allows opening the document with restrictions.
	UserPassword string

	// OwnerPassword allows opening the document with full access.
	// If empty, defaults to UserPassword.
	OwnerPassword string

	// Permissions specifies what operations are allowed (print, copy, etc.).
	Permissions Permission

	// KeyLength specifies the encryption key length in bits (40 or 128).
	KeyLength int

	// FileID is the document's unique identifier from the trailer dictionary.
	FileID string
}

EncryptionConfig holds the encryption configuration for a PDF document.

func (*EncryptionConfig) Validate

func (c *EncryptionConfig) Validate() error

Validate checks if the encryption config is valid.

type EncryptionDict

type EncryptionDict struct {
	// Filter is always "/Standard" for Standard Security Handler.
	Filter string

	// V is the algorithm version (1 for 40-bit RC4, 2 for 128-bit RC4, 4 for AES-128, 5 for AES-256).
	V int

	// R is the algorithm revision (2 for 40-bit RC4, 3 for 128-bit RC4, 4 for AES-128, 6 for AES-256).
	R int

	// Length is the key length in bits (40, 128, or 256).
	Length int

	// P is the permission flags (32-bit integer).
	P int32

	// O is the owner password hash (32 bytes for RC4, variable for AES).
	O []byte

	// U is the user password hash (32 bytes for RC4, variable for AES).
	U []byte

	// CFM is the crypt filter method (empty for RC4, "AESV2" for AES-128, "AESV3" for AES-256).
	CFM string
}

EncryptionDict represents the PDF encryption dictionary.

type EncryptionInfo added in v0.6.0

type EncryptionInfo struct {
	Filter string // /Filter — should be "Standard"
	V      int    // /V — algorithm version (1, 2, or 4)
	R      int    // /R — algorithm revision (2, 3, or 4)
	Length int    // /Length — key length in bits (40 or 128)
	P      int32  // /P — permission flags
	O      []byte // /O — owner password hash (32 bytes)
	U      []byte // /U — user password hash (32 bytes)
	FileID []byte // First element of trailer /ID array
	CFM    string // /CFM from /CF./StdCF (empty for RC4, "AESV2" for AES-128)
}

EncryptionInfo holds values parsed from the /Encrypt dictionary and trailer. These are used to verify the password and derive decryption keys.

type Permission

type Permission int32

Permission represents PDF document permissions.

These flags control what operations are allowed on an encrypted PDF. Multiple permissions can be combined using the OR operator (|).

Example:

perms := PermissionPrint | PermissionCopy | PermissionModify
const (
	// PermissionPrint allows printing the document (bit 3).
	PermissionPrint Permission = 1 << 2

	// PermissionModify allows modifying the document (bit 4).
	PermissionModify Permission = 1 << 3

	// PermissionCopy allows copying text and graphics (bit 5).
	PermissionCopy Permission = 1 << 4

	// PermissionAnnotate allows adding or modifying annotations (bit 6).
	PermissionAnnotate Permission = 1 << 5

	// PermissionFillForms allows filling form fields (bit 9).
	PermissionFillForms Permission = 1 << 8

	// PermissionExtract allows extracting text for accessibility (bit 10).
	PermissionExtract Permission = 1 << 9

	// PermissionAssemble allows assembling the document (bit 11).
	PermissionAssemble Permission = 1 << 10

	// PermissionPrintHighQuality allows high-quality printing (bit 12).
	PermissionPrintHighQuality Permission = 1 << 11

	// PermissionAll grants all permissions.
	PermissionAll Permission = PermissionPrint |
		PermissionModify |
		PermissionCopy |
		PermissionAnnotate |
		PermissionFillForms |
		PermissionExtract |
		PermissionAssemble |
		PermissionPrintHighQuality

	// PermissionNone grants no permissions (default).
	PermissionNone Permission = 0
)

func (Permission) Add

func (p Permission) Add(perm Permission) Permission

Add adds a permission to the current permissions.

Example:

perms := PermissionPrint
perms = perms.Add(PermissionCopy)

func (Permission) Has

func (p Permission) Has(perm Permission) bool

Has checks if a specific permission is granted.

Example:

perms := PermissionPrint | PermissionCopy
if perms.Has(PermissionPrint) {
    fmt.Println("Printing allowed")
}

func (Permission) Remove

func (p Permission) Remove(perm Permission) Permission

Remove removes a permission from the current permissions.

Example:

perms := PermissionAll
perms = perms.Remove(PermissionModify)

func (Permission) String

func (p Permission) String() string

String returns a human-readable string of enabled permissions.

func (Permission) ToPDFValue

func (p Permission) ToPDFValue() int32

ToPDFValue converts permissions to the PDF integer format.

The PDF specification requires bits 1, 2, 7, 8 to be set to 1, and all other bits depend on the actual permissions.

type RC4Encryptor

type RC4Encryptor struct {
	// contains filtered or unexported fields
}

RC4Encryptor handles RC4 encryption/decryption for PDF objects.

func NewRC4Encryptor

func NewRC4Encryptor(config *EncryptionConfig) (*RC4Encryptor, error)

NewRC4Encryptor creates a new RC4 encryptor with the given configuration.

func (*RC4Encryptor) GetEncryptionDict

func (e *RC4Encryptor) GetEncryptionDict() *EncryptionDict

GetEncryptionDict returns the encryption dictionary.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL