SnmpKit.SnmpLib.Security.Priv (snmpkit v0.6.4)
Implements SNMPv3 privacy protocols for message encryption and decryption.
This module provides support for standard SNMPv3 privacy protocols like DES and AES, ensuring data confidentiality in SNMP communications.
Supported Protocols
:none
- No privacy:des
- DES-CBC (56-bit):aes128
- AES-CFB128 (128-bit):aes192
- AES-CFB128 (192-bit):aes256
- AES-CFB128 (256-bit)
Security Considerations
- DES is considered weak and should only be used for compatibility with legacy devices.
- AES protocols are recommended for strong encryption.
- Keys should be derived securely using the functions in
SnmpKit.SnmpLib.Security.Keys
.
Protocol Selection Guidelines
- For new deployments, prefer
:aes256
for the strongest security. - Use
:aes128
for a balance of performance and security. - Use
:des
only when required for interoperability.
Technical Details
This module implements the privacy aspects of the User-Based Security Model (USM) as defined in RFC 3414 and RFC 3826.
Key Derivation
Privacy keys are derived from the user's password and the authoritative SNMP
engine's ID. This process is handled by the Keys
module.
Initialization Vectors
For CBC and CFB modes, a unique Initialization Vector (IV) is required for each
encryption operation. This IV is generated and included in the privParameters
field of the SNMPv3 message.
Padding
The plaintext data is padded to match the block size of the cipher before encryption. This padding is removed upon decryption.
Usage Examples
This module is typically used internally by the USM
module.
Message Encryption
# Assuming keys are derived and user is configured
priv_key = derived_privacy_key
auth_key = derived_authentication_key # Required for IV generation
plaintext = "confidential SNMP data"
{:ok, {ciphertext, priv_params}} = SnmpKit.SnmpLib.Security.Priv.encrypt(
:aes256, priv_key, auth_key, plaintext
)
# Decrypt message
{:ok, decrypted} = SnmpKit.SnmpLib.Security.Priv.decrypt(
:aes256, priv_key, auth_key, ciphertext, priv_params
)
assert decrypted == plaintext
Protocol Information
iex> SnmpKit.SnmpLib.Security.Priv.protocol_info(:aes128)
%{algorithm: :aes_128_cfb128, key_size: 16, iv_size: 16, block_size: 16}
Summary
Functions
Benchmarks the performance of a given privacy protocol.
Decrypts ciphertext using the specified privacy protocol.
Decrypts a batch of ciphertexts efficiently.
Encrypts plaintext using the specified privacy protocol.
Encrypts a batch of plaintexts efficiently.
Retrieves the specification for a given privacy protocol.
Checks if a protocol is considered cryptographically secure.
Returns a list of cryptographically secure protocols.
Returns a list of all supported privacy protocols.
Validates if a privacy key is compliant with the protocol's requirements.
Types
Functions
@spec benchmark_protocol( priv_protocol(), priv_key(), auth_key(), plaintext(), non_neg_integer() ) :: %{encrypt_us: float(), decrypt_us: float(), ops_per_sec: float()}
Benchmarks the performance of a given privacy protocol.
@spec decrypt(priv_protocol(), priv_key(), auth_key(), ciphertext(), priv_params()) :: {:ok, plaintext()} | {:error, atom()}
Decrypts ciphertext using the specified privacy protocol.
Parameters
protocol
: Privacy protocol used for encryptionpriv_key
: Privacy key (same as used for encryption)auth_key
: Authentication key (used for IV validation)ciphertext
: Encrypted datapriv_params
: Privacy parameters from encryption (contains IV)
Returns
{:ok, plaintext}
: Decryption successful{:error, reason}
: Decryption failed
Examples
# AES-256 decryption
{:ok, plaintext} = SnmpKit.SnmpLib.Security.Priv.decrypt(
:aes256, priv_key, auth_key, ciphertext, priv_params
)
# Handle decryption errors
case SnmpKit.SnmpLib.Security.Priv.decrypt(:des, priv_key, auth_key, ciphertext, priv_params) do
{:ok, plaintext} -> process_plaintext(plaintext)
{:error, :decryption_failed} -> handle_corruption()
{:error, :invalid_padding} -> handle_padding_error()
end
@spec decrypt_batch( priv_protocol(), priv_key(), auth_key(), [{ciphertext(), priv_params()}] ) :: [ok: plaintext(), error: atom()]
Decrypts a batch of ciphertexts efficiently.
@spec encrypt(priv_protocol(), priv_key(), auth_key(), plaintext()) :: {:ok, {ciphertext(), priv_params()}} | {:error, atom()}
Encrypts plaintext using the specified privacy protocol.
Parameters
protocol
: Privacy protocol to usepriv_key
: Privacy key for the chosen protocolauth_key
: Authentication key (used for IV generation)plaintext
: Data to encrypt
Returns
{:ok, {ciphertext, priv_params}}
: Encryption successful{:error, reason}
: Encryption failed
Examples
# AES-128 encryption
{:ok, {ciphertext, priv_params}} = SnmpKit.SnmpLib.Security.Priv.encrypt(
:aes128, priv_key, auth_key, "secret data"
)
@spec encrypt_batch(priv_protocol(), priv_key(), auth_key(), [plaintext()]) :: {:ok, [{ciphertext(), priv_params()}]} | {:error, atom()}
Encrypts a batch of plaintexts efficiently.
Examples
iex> plaintexts = ["msg1", "msg2"]
iex> {:ok, encrypted_list} = Priv.encrypt_batch(:aes128, priv_key, auth_key, plaintexts)
iex> length(encrypted_list)
2
@spec protocol_info(priv_protocol()) :: map() | nil
Retrieves the specification for a given privacy protocol.
Returns a map with :algorithm
, :key_size
, :iv_size
, and :block_size
,
or nil
if the protocol is unsupported.
Examples
iex> Priv.protocol_info(:aes128)
%{algorithm: :aes_128_cfb128, key_size: 16, iv_size: 16, block_size: 16}
iex> Priv.protocol_info(:unsupported)
nil
@spec secure_protocol?(priv_protocol()) :: boolean()
Checks if a protocol is considered cryptographically secure.
@spec secure_protocols() :: [priv_protocol()]
Returns a list of cryptographically secure protocols.
@spec supported_protocols() :: [priv_protocol()]
Returns a list of all supported privacy protocols.
@spec validate_key(priv_protocol(), priv_key()) :: :ok | {:error, atom()}
Validates if a privacy key is compliant with the protocol's requirements.
Examples
iex> Priv.validate_key(:aes128, :crypto.strong_rand_bytes(16))
:ok
iex> Priv.validate_key(:des, <<1, 2, 3>>)
{:error, :invalid_key_size}