SNMPv3用户安全模型

发布时间 2023-12-20 16:28:24作者: 纯真丁一郎です

1. 前言部分

SNMPv3与SNMPv2相比有了很大的改进,主要体现在安全性方面:

  1. 用户认证机制 - SNMPv3改用基于用户的安全模型(USM),需要替换v2中的社区字符串认证机制(community strings),实现用户管理、认证和加密。

  2. 加密与数据完整性检查 - 需要添加支持加密传输和数据完整性检查的模块,如SHA、MD5等算法。v2没有加密机制。

  3. 授权与访问控制 - 添加基于视图(view-based access control,VACM)的访问控制模型模块以及授权处理。以控制访问 SNMP 代理的哪些数据。

  4. 安全参数与配置 - 添加安全级别参数设置、安全密钥配置等与安全相关的数据结构与存储。

  5. 消息处理过程 - message handling processes中加入处理安全参数、认证、加密与解密、授权检查等步骤

主要是在安全性、认证、加密、访问控制等方面下功夫,与SNMPv2形成明显对比。这需要对原有的代码流程进行较大的修改。

2. 模型元素

根据RFC3414规范,SNMPv3在用户安全模型(USM)方面做了如下的关键定义:

USM Users

定义了用户的数据模型,包括用户名称、认证协议算法、本地化密钥等安全相关的参数。这是基于用户实现安全性的基础,包括:

  • userName:用户名称

  • securityName:与模型无关的安全名称

  • authProtocol:认证协议

  • authKey:认证密钥

  • authKeyChange:远程更新认证密钥

  • privProtocol:隐私保护协议

  • privKey:隐私保护密钥

  • privKeyChange:远程更新隐私保护密钥

这些属性中,有的用于标识用户,有的则定义了保证安全性所需要的密钥、认证协议等信息。

注意每种密钥可基于不同设备配置不同值,且不能通过SNMP本身读取,只能通过特定安全机制来远程更新。

重放保护机制

定义了时间同步机制,防止重放攻击。

  1. 每个SNMP引擎维护了三个对象:
  • snmpEngineID:唯一标识一个SNMP引擎

  • snmpEngineBoots:启动计数器

  • snmpEngineTime:运行时间计数器

  1. 引入了msgAuthoritativeEngineID参数,包含权威引擎ID,用于防重放攻击。

  2. 同步沿用了snmpEngineBoots和snmpEngineTime的值,以识别过期消息。

  3. 描述了初始值配置,时钟回拨,时钟同步的处理过程。非权威引擎需要同步这些值。

  4. 定义了时间窗口的概念,在该窗口内的消息被视为有效。

  5. 详细阐述了时钟同步的过程,即接收端获取最新权威时钟计数器,并检查其落在时间窗口内。

工作流程是:

  1. 消息中包含上面三个参数的值。

  2. 接收方根据这些参数,判断消息是否为重放旧消息。

  3. 同时根据权威引擎同步最新计数器值。

这种基于引擎唯一ID和计数器的防重放机制可以确保安全性。

USM消息格式

定义了USM安全参数的数据格式,包含关键安全参数元素的ASN.1格式,以便消息传递。

SNMPv3消息格式遵循version-specific的消息处理模型文档定义,如RFC3412。
msgSecurityParameters字段采用OCTET STRING类型,值为USMSecurityParameters ASN.1序列化后的BER编码。

   USMSecurityParametersSyntax DEFINITIONS IMPLICIT TAGS ::= BEGIN

      UsmSecurityParameters ::=
          SEQUENCE {
           -- global User-based security parameters
              msgAuthoritativeEngineID     OCTET STRING,
              msgAuthoritativeEngineBoots  INTEGER (0..2147483647),
              msgAuthoritativeEngineTime   INTEGER (0..2147483647),
              msgUserName                  OCTET STRING (SIZE(1..32)),
           -- authentication protocol specific parameters
              msgAuthenticationParameters  OCTET STRING,
           -- privacy protocol specific parameters
              msgPrivacyParameters         OCTET STRING
          }
   END

USM安全参数(msgSecurityParameters)中各个字段的具体含义:

  • msgAuthoritativeEngineID:授权的引擎ID,表示本次消息交互涉及的授权SNMP引擎的标识符。

  • msgAuthoritativeEngineBoots:授权引擎的启动计数器,用于重放保护检测。

  • msgAuthoritativeEngineTime: 授权引擎的时间计数器,用于重放保护。

  • msgUserName: 代表本次消息的用户名称。如果为空则仅用于引擎ID发现。

  • msgAuthenticationParameters:根据usmUserTable中配置的认证协议的参数。

  • msgPrivacyParameters:根据usmUserTable中配置的隐私保护协议的参数。

USM服务接口

定义了USM的服务接口,包括生成请求和响应消息的服务原语。这为USM模块提供了标准化接口。

Outgoing SNMP Message

主要描述了USM模块为SNMP消息处理(Message Processing)子系统生成外发SNMP消息所提供的服务和数据元素。

包含了两个服务:

  • generateRequestMsg: 生成Request请求消息

  • generateResponseMsg: 生成Response响应消息

1) A service to generate a Request message. The abstract service primitive is:

      statusInformation =            -- success or errorIndication
        generateRequestMsg(
        IN   messageProcessingModel  -- typically, SNMP version
        IN   globalData              -- message header, admin data
        IN   maxMessageSize          -- of the sending SNMP entity
        IN   securityModel           -- for the outgoing message
        IN   securityEngineID        -- authoritative SNMP entity
        IN   securityName            -- on behalf of this principal
        IN   securityLevel           -- Level of Security requested
        IN   scopedPDU               -- message (plaintext) payload
        OUT  securityParameters      -- filled in by Security Module
        OUT  wholeMsg                -- complete generated message
        OUT  wholeMsgLength          -- length of generated message
             )

2) A service to generate a Response message. The abstract service primitive is:

      statusInformation =            -- success or errorIndication
        generateResponseMsg(
        IN   messageProcessingModel  -- typically, SNMP version
        IN   globalData              -- message header, admin data
        IN   maxMessageSize          -- of the sending SNMP entity
        IN   securityModel           -- for the outgoing message
        IN   securityEngineID        -- authoritative SNMP entity
        IN   securityName            -- on behalf of this principal
        IN   securityLevel           -- Level of Security requested
        IN   scopedPDU               -- message (plaintext) payload
        IN   securityStateReference  -- reference to security state
                                     -- information from original
                                     -- request
        OUT  securityParameters      -- filled in by Security Module
        OUT  wholeMsg                -- complete generated message
        OUT  wholeMsgLength          -- length of generated message
             )

Note: 这只是概念上的抽象服务接口,具体的实现可能因编程语言和平台而异。

这部分定义了USM模块生成安全性SNMP消息服务接口的参数和元素,主要有以下几类:

  • messageProcessingModel:SNMP版本等信息

  • securityModel/Level/Name/ID:安全模型和级别相关信息

  • scopedPDU:实际的消息 payload

  • securityStateReference: 对response消息的cache引用

  • statusInformation:返回生成消息的状态

  • securityParameters:安全参数,由USM填充

  • wholeMsg:生成的完整消息

密钥本地化

这部分描述了密钥本地化(Key Localization)的算法,目的是使得不同设备上同一用户的实际密钥可以不同,提高安全性。其流程是:

  1. 用户的密码先通过哈希算法转换为一个主密钥Ku。附录给出了MD5和SHA两种算法。

  2. 然后,将授权引擎E的snmpEngineID追加到Ku后面,再将Ku追加到上一步的结果后面。这样就把snmpEngineID包裹在两个Ku之间。

  3. 最后调用安全哈希算法(根据用户U在引擎E上的配置的认证协议选择是MD5还是SHA),输入为上一步的拼接结果。输出hash后的值就是用户U在该引擎E上的最终本地化密钥Kul。

这样不同设备根据各自的snmpEngineID,通过hash计算都可以得到不同的本地化密钥,提高了安全性,防止主密钥泄露后被全局利用。

3. 过程元素

描述了SNMP(简单网络管理协议)收到一个代表用户的带有特定安全级别的管理操作的消息时遵循的消息发送和接收端的处理流程。

Generating an Outgoing SNMP Message

具体步骤包括:

  1. 基于安全状态引用或安全名称提取用户信息。

  2. 检查安全级别是否规定消息需要被保护免于泄露,以及用户是否支持认证和隐私协议。

  3. 检查安全级别是否规定消息需要被认证,以及用户是否支持认证协议。

  4. 如果安全级别规定消息需要被保护免于泄露,就对消息进行加密。

  5. 将securityEngineID编码为OCTET STRING,然后放入securityParameters的msgAuthoritativeEngineID字段。

  6. 如果安全级别规定消息需要被认证,就使用来自LCD的securityEngineID对应的snmpEngineBoots和snmpEngineTime的当前值。

  7. 将userName编码为OCTET STRING,然后放入securityParameters的msgUserName字段。

  8. 如果安全级别规定消息需要被认证,就根据用户的认证协议对消息进行认证。

  9. 将完成的消息及其长度返回给调用模块,同时将statusInformation设置为成功。

Processing an Incoming SNMP Message

具体步骤包括:

  1. 检查收到的securityParameters是否为UsmSecurityParameters定义的OCTET STRING格式的序列化。如果不是,则增加snmpInASNParseErrs计数器,并返回错误指示(parseError)给调用模块。

  2. 从securityParameters中提取安全参数字段的值。返回给调用者的securityEngineID的值是msgAuthoritativeEngineID字段的值。准备cachedSecurityData并准备一个securityStateReference来引用这些数据。需要缓存的值包括:msgUserName。

  3. 如果securityParameters中msgAuthoritativeEngineID字段的值未知,则有两种选择:a) 执行发现的非权威SNMP引擎可以选择在其本地配置数据存储(LCD)中创建一个新条目并继续处理;或者b) 增加usmStatsUnknownEngineIDs计数器,并返回一个错误指示(unknownEngineID)以及增加计数器的OID和值给调用模块。

  4. 从本地配置数据存储(LCD, usmUserTable)中提取msgUserName和msgAuthoritativeEngineID字段的值的信息。如果没有关于用户的信息,那么usmStatsUnknownUserNames计数器将会增加,并且一个错误指示(unknownSecurityName)以及增加计数器的OID和值将会返回给调用模块。

  5. 如果用户的信息表明用户不支持调用者请求的securityLevel,那么usmStatsUnsupportedSecLevels计数器将会增加,并且一个错误指示(unsupportedSecurityLevel)以及增加计数器的OID和值将会返回给调用模块。

  6. 如果securityLevel指定消息需要被认证,那么消息将根据用户的认证协议进行认证。这通过调用实现用户认证协议的认证模块来完成,该模块遵循以下抽象服务原语:

   statusInformation =          -- success or failure
     authenticateIncomingMsg(
     IN   authKey               -- the user's localized authKey
      IN   authParameters        -- as received on the wire
      IN   wholeMsg              -- as received on the wire
      OUT  authenticatedWholeMsg -- checked for authentication
           )

如果认证模块返回失败,那么消息不能被信任,因此usmStatsWrongDigests计数器会增加,并且一个错误指示(authenticationFailure)以及增加计数器的OID和值将会返回给调用模块。如果认证模块返回成功,那么消息是真实的并且可以被信任,因此继续处理。

  1. 根据用户认证协议的认证模块的判断,做出不同的处理

检查时间窗口:

  • 如果消息是经过身份验证的,从本地配置数据存储中提取与 msgAuthoritativeEngineID 相关的本地值。
  • 如果消息来自授权的 SNMP 引擎,检查时间窗口条件:
  • 如果满足任一条件(本地 snmpEngineBoots 为最大值、msgAuthoritativeEngineBoots 与本地值不同、msgAuthoritativeEngineTime 与本地 snmpEngineTime 差异大于 +/- 150 秒),则认为消息不在时间窗口内。
  • 在消息不在时间窗口内的情况下,增加错误计数器并返回错误指示(notInTimeWindow)。

处理非授权的 SNMP 引擎情况:

  • 如果消息来自非授权的 SNMP 引擎,执行以下步骤:
  • 如果条件满足(msgAuthoritativeEngineBoots 大于本地值或者等于本地值但 msgAuthoritativeEngineTime 大于 latestReceivedEngineTime),则更新本地配置数据存储的相关值。
  • 如果条件满足(本地 snmpEngineBoots 为最大值、msgAuthoritativeEngineBoots 小于本地值、或者msgAuthoritativeEngineBoots 等于本地值但 msgAuthoritativeEngineTime 与本地 snmpEngineTime 差异大于 150 秒),则认为消息不在时间窗口内。
  • 在消息不在时间窗口内的情况下,返回错误指示(notInTimeWindow)。
  1. 如果securityLevel指示消息被保护免于泄露,那么根据用户的隐私协议对表示序列化scopedPDU的字节序列进行解密,以获得未加密的序列化scopedPDU值。这通过调用实现用户隐私协议的隐私模块来完成,该模块遵循以下抽象原语:
   statusInformation =       -- success or failure
     decryptData(
     IN    decryptKey        -- the user's localized privKey
     IN    privParameters    -- as received on the wire
     IN    encryptedData     -- encryptedPDU as received
     OUT   decryptedData     -- serialized decrypted scopedPDU
           )

如果隐私模块返回失败,那么消息不能被处理,因此usmStatsDecryptionErrors计数器会增加,并且一个错误指示(decryptionError)以及增加计数器的OID和值将会返回给调用模块。如果隐私模块返回成功,那么解密的scopedPDU是要返回给调用模块的消息有效载荷。否则,假定scopedPDU组件是明文,并且是要返回给调用模块的消息有效载荷。

  1. 计算 maxSizeResponseScopedPDU,这是可能的响应消息的 scopedPDU 允许的最大大小。

  2. 从 usmUserTable 中检索用户的 securityName。

  3. 将安全数据缓存为 cachedSecurityData,以便对该消息的可能响应可以使用相同的身份验证和隐私密钥。

  4. 将 statusInformation 设置为 success,并根据 processIncomingMsg 原语中指定的 OUT 参数返回到调用模块。

4. 发现过程

这段文本描述了用户安全模型(User-based Security Model)中的发现过程。

  1. 发现需求: 用户安全模型要求进行发现过程,以获取有关其他 SNMP 引擎的足够信息,以便与它们进行通信。发现需要一个非授权的 SNMP 引擎在通信之前了解授权的 SNMP 引擎的 snmpEngineID 值。可以通过生成一个带有 securityLevel 为 noAuthNoPriv、msgUserName 为空、msgAuthoritativeEngineID 为零长度、以及 varBindList 为空的 Request 消息来实现。对这条消息的响应将是一个 Report 消息,其中包含授权的 SNMP 引擎的 snmpEngineID 作为 msgSecurityParameters 字段内 msgAuthoritativeEngineID 字段的值。它包含一个带有 varBindList 中的 usmStatsUnknownEngineIDs 计数器的 Report PDU。

  2. 需要身份验证的通信: 如果需要身份验证通信,发现过程还应该与授权的 SNMP 引擎建立时间同步。可以通过发送一个经过身份验证的 Request 消息,其中 msgAuthoritativeEngineID 的值设置为新学到的 snmpEngineID,msgAuthoritativeEngineBoots 和 msgAuthoritativeEngineTime 的值设置为零来实现。对于经过身份验证的 Request 消息,必须在 msgUserName 字段中使用有效的 userName。对这条经过身份验证的消息的响应将是一个 Report 消息,其中包含授权的 SNMP 引擎的 snmpEngineBoots 和 snmpEngineTime 的最新值,分别作为 msgAuthoritativeEngineBoots 和 msgAuthoritativeEngineTime 字段的值。它还包含 Report PDU 的 varBindList 中的 usmStatsNotInTimeWindows 计数器。然后,时间同步会自动发生,作为处理 非授权的 SNMP 引擎情况程序 的一部分。另请参阅第 2.3 节。

5. 定义

关键的数据结构和元素的规范定义

点击查看代码
SNMP-USER-BASED-SM-MIB DEFINITIONS ::= BEGIN

IMPORTS
    MODULE-IDENTITY, OBJECT-TYPE,
    OBJECT-IDENTITY,
    snmpModules, Counter32                FROM SNMPv2-SMI
    TEXTUAL-CONVENTION, TestAndIncr,
    RowStatus, RowPointer,
    StorageType, AutonomousType           FROM SNMPv2-TC
    MODULE-COMPLIANCE, OBJECT-GROUP       FROM SNMPv2-CONF
    SnmpAdminString, SnmpEngineID,
    snmpAuthProtocols, snmpPrivProtocols  FROM SNMP-FRAMEWORK-MIB;

snmpUsmMIB MODULE-IDENTITY
    LAST-UPDATED "200210160000Z"            -- 16 Oct 2002, midnight
    ORGANIZATION "SNMPv3 Working Group"
    CONTACT-INFO "WG-email:   snmpv3@lists.tislabs.com
                  Subscribe:  majordomo@lists.tislabs.com
                              In msg body:  subscribe snmpv3

                  Chair:      Russ Mundy
                              Network Associates Laboratories
                  postal:     15204 Omega Drive, Suite 300
                              Rockville, MD 20850-4601
                              USA
                  email:      mundy@tislabs.com

                  phone:      +1 301-947-7107

                  Co-Chair:   David Harrington
                              Enterasys Networks
                  Postal:     35 Industrial Way
                              P. O. Box 5004
                              Rochester, New Hampshire 03866-5005
                              USA
                  EMail:      dbh@enterasys.com
                  Phone:      +1 603-337-2614

                  Co-editor   Uri Blumenthal
                              Lucent Technologies
                  postal:     67 Whippany Rd.
                              Whippany, NJ 07981
                              USA
                  email:      uri@lucent.com
                  phone:      +1-973-386-2163

                  Co-editor:  Bert Wijnen
                              Lucent Technologies
                  postal:     Schagen 33
                              3461 GL Linschoten
                              Netherlands
                  email:      bwijnen@lucent.com
                  phone:      +31-348-480-685
                 "
    DESCRIPTION  "The management information definitions for the
                  SNMP User-based Security Model.

                  Copyright (C) The Internet Society (2002). This
                  version of this MIB module is part of RFC 3414;
                  see the RFC itself for full legal notices.
                 "
--  Revision history

    REVISION     "200210160000Z"          -- 16 Oct 2002, midnight
    DESCRIPTION  "Changes in this revision:
                  - Updated references and contact info.
                  - Clarification to usmUserCloneFrom DESCRIPTION
                    clause
                  - Fixed 'command responder' into 'command generator'
                    in last para of DESCRIPTION clause of
                    usmUserTable.
                  This revision published as RFC3414.
                 "
    REVISION     "199901200000Z"          -- 20 Jan 1999, midnight
    DESCRIPTION  "Clarifications, published as RFC2574"

    REVISION     "199711200000Z"          -- 20 Nov 1997, midnight
    DESCRIPTION  "Initial version, published as RFC2274"

    ::= { snmpModules 15 }

-- Administrative assignments ****************************************

usmMIBObjects     OBJECT IDENTIFIER ::= { snmpUsmMIB 1 }
usmMIBConformance OBJECT IDENTIFIER ::= { snmpUsmMIB 2 }

-- Identification of Authentication and Privacy Protocols ************

usmNoAuthProtocol OBJECT-IDENTITY
    STATUS        current
    DESCRIPTION  "No Authentication Protocol."
    ::= { snmpAuthProtocols 1 }

usmHMACMD5AuthProtocol OBJECT-IDENTITY
    STATUS        current
    DESCRIPTION  "The HMAC-MD5-96 Digest Authentication Protocol."
    REFERENCE    "- H. Krawczyk, M. Bellare, R. Canetti HMAC:
                    Keyed-Hashing for Message Authentication,
                    RFC2104, Feb 1997.
                  - Rivest, R., Message Digest Algorithm MD5, RFC1321.
                 "
    ::= { snmpAuthProtocols 2 }

usmHMACSHAAuthProtocol OBJECT-IDENTITY
    STATUS        current
    DESCRIPTION  "The HMAC-SHA-96 Digest Authentication Protocol."
    REFERENCE    "- H. Krawczyk, M. Bellare, R. Canetti, HMAC:
                    Keyed-Hashing for Message Authentication,
                    RFC2104, Feb 1997.
                  - Secure Hash Algorithm. NIST FIPS 180-1.
                 "
    ::= { snmpAuthProtocols 3 }

usmNoPrivProtocol OBJECT-IDENTITY
    STATUS        current
    DESCRIPTION  "No Privacy Protocol."
    ::= { snmpPrivProtocols 1 }

usmDESPrivProtocol OBJECT-IDENTITY
    STATUS        current
    DESCRIPTION  "The CBC-DES Symmetric Encryption Protocol."
    REFERENCE    "- Data Encryption Standard, National Institute of
                    Standards and Technology.  Federal Information
                    Processing Standard (FIPS) Publication 46-1.

                    Supersedes FIPS Publication 46,
                    (January, 1977; reaffirmed January, 1988).

                  - Data Encryption Algorithm, American National
                    Standards Institute.  ANSI X3.92-1981,
                    (December, 1980).

                  - DES Modes of Operation, National Institute of
                    Standards and Technology.  Federal Information
                    Processing Standard (FIPS) Publication 81,
                    (December, 1980).

                  - Data Encryption Algorithm - Modes of Operation,
                    American National Standards Institute.
                    ANSI X3.106-1983, (May 1983).
                 "
    ::= { snmpPrivProtocols 2 }

-- Textual Conventions ***********************************************

KeyChange ::=     TEXTUAL-CONVENTION
   STATUS         current
   DESCRIPTION
         "Every definition of an object with this syntax must identify
          a protocol P, a secret key K, and a hash algorithm H
          that produces output of L octets.

          The object's value is a manager-generated, partially-random
          value which, when modified, causes the value of the secret
          key K, to be modified via a one-way function.

          The value of an instance of this object is the concatenation
          of two components: first a 'random' component and then a
          'delta' component.

          The lengths of the random and delta components
          are given by the corresponding value of the protocol P;
          if P requires K to be a fixed length, the length of both the
          random and delta components is that fixed length; if P
          allows the length of K to be variable up to a particular
          maximum length, the length of the random component is that
          maximum length and the length of the delta component is any
          length less than or equal to that maximum length.
          For example, usmHMACMD5AuthProtocol requires K to be a fixed
          length of 16 octets and L - of 16 octets.
          usmHMACSHAAuthProtocol requires K to be a fixed length of
          20 octets and L - of 20 octets. Other protocols may define
          other sizes, as deemed appropriate.

          When a requester wants to change the old key K to a new
          key keyNew on a remote entity, the 'random' component is
          obtained from either a true random generator, or from a
          pseudorandom generator, and the 'delta' component is
          computed as follows:

           - a temporary variable is initialized to the existing value
             of K;
           - if the length of the keyNew is greater than L octets,
             then:
              - the random component is appended to the value of the
                temporary variable, and the result is input to the
                the hash algorithm H to produce a digest value, and
                the temporary variable is set to this digest value;
              - the value of the temporary variable is XOR-ed with
                the first (next) L-octets (16 octets in case of MD5)
                of the keyNew to produce the first (next) L-octets
                (16 octets in case of MD5) of the 'delta' component.
              - the above two steps are repeated until the unused
                portion of the keyNew component is L octets or less,
           - the random component is appended to the value of the
             temporary variable, and the result is input to the
             hash algorithm H to produce a digest value;
           - this digest value, truncated if necessary to be the same
             length as the unused portion of the keyNew, is XOR-ed
             with the unused portion of the keyNew to produce the
             (final portion of the) 'delta' component.

           For example, using MD5 as the hash algorithm H:

              iterations = (lenOfDelta - 1)/16; /* integer division */
              temp = keyOld;
              for (i = 0; i < iterations; i++) {
                  temp = MD5 (temp || random);
                  delta[i*16 .. (i*16)+15] =
                         temp XOR keyNew[i*16 .. (i*16)+15];
              }
              temp = MD5 (temp || random);
              delta[i*16 .. lenOfDelta-1] =
                     temp XOR keyNew[i*16 .. lenOfDelta-1];

          The 'random' and 'delta' components are then concatenated as
          described above, and the resulting octet string is sent to
          the recipient as the new value of an instance of this object.

          At the receiver side, when an instance of this object is set
          to a new value, then a new value of K is computed as follows:

           - a temporary variable is initialized to the existing value
             of K;
           - if the length of the delta component is greater than L
             octets, then:
              - the random component is appended to the value of the
                temporary variable, and the result is input to the
                hash algorithm H to produce a digest value, and the
                temporary variable is set to this digest value;
              - the value of the temporary variable is XOR-ed with
                the first (next) L-octets (16 octets in case of MD5)
                of the delta component to produce the first (next)
                L-octets (16 octets in case of MD5) of the new value
                of K.
              - the above two steps are repeated until the unused
                portion of the delta component is L octets or less,
           - the random component is appended to the value of the
             temporary variable, and the result is input to the
             hash algorithm H to produce a digest value;
           - this digest value, truncated if necessary to be the same
             length as the unused portion of the delta component, is
             XOR-ed with the unused portion of the delta component to
             produce the (final portion of the) new value of K.

           For example, using MD5 as the hash algorithm H:

              iterations = (lenOfDelta - 1)/16; /* integer division */
              temp = keyOld;
              for (i = 0; i < iterations; i++) {
                  temp = MD5 (temp || random);
                  keyNew[i*16 .. (i*16)+15] =
                         temp XOR delta[i*16 .. (i*16)+15];
              }
              temp = MD5 (temp || random);
              keyNew[i*16 .. lenOfDelta-1] =
                     temp XOR delta[i*16 .. lenOfDelta-1];

          The value of an object with this syntax, whenever it is
          retrieved by the management protocol, is always the zero
          length string.

          Note that the keyOld and keyNew are the localized keys.

          Note that it is probably wise that when an SNMP entity sends
          a SetRequest to change a key, that it keeps a copy of the old
          key until it has confirmed that the key change actually
          succeeded.
         "
    SYNTAX       OCTET STRING

-- Statistics for the User-based Security Model **********************


usmStats         OBJECT IDENTIFIER ::= { usmMIBObjects 1 }


usmStatsUnsupportedSecLevels OBJECT-TYPE
    SYNTAX       Counter32
    MAX-ACCESS   read-only
    STATUS       current
    DESCRIPTION "The total number of packets received by the SNMP
                 engine which were dropped because they requested a
                 securityLevel that was unknown to the SNMP engine
                 or otherwise unavailable.
                "
    ::= { usmStats 1 }

usmStatsNotInTimeWindows OBJECT-TYPE
    SYNTAX       Counter32
    MAX-ACCESS   read-only
    STATUS       current
    DESCRIPTION "The total number of packets received by the SNMP
                 engine which were dropped because they appeared
                 outside of the authoritative SNMP engine's window.
                "
    ::= { usmStats 2 }

usmStatsUnknownUserNames OBJECT-TYPE
    SYNTAX       Counter32
    MAX-ACCESS   read-only
    STATUS       current
    DESCRIPTION "The total number of packets received by the SNMP
                 engine which were dropped because they referenced a
                 user that was not known to the SNMP engine.
                "
    ::= { usmStats 3 }

usmStatsUnknownEngineIDs OBJECT-TYPE
    SYNTAX       Counter32
    MAX-ACCESS   read-only
    STATUS       current
    DESCRIPTION "The total number of packets received by the SNMP
                 engine which were dropped because they referenced an
                 snmpEngineID that was not known to the SNMP engine.
                "
    ::= { usmStats 4 }

usmStatsWrongDigests OBJECT-TYPE

    SYNTAX       Counter32
    MAX-ACCESS   read-only
    STATUS       current
    DESCRIPTION "The total number of packets received by the SNMP
                 engine which were dropped because they didn't
                 contain the expected digest value.
                "
    ::= { usmStats 5 }

usmStatsDecryptionErrors OBJECT-TYPE
    SYNTAX       Counter32
    MAX-ACCESS   read-only
    STATUS       current
    DESCRIPTION "The total number of packets received by the SNMP
                 engine which were dropped because they could not be
                 decrypted.
                "
    ::= { usmStats 6 }

-- The usmUser Group ************************************************

usmUser          OBJECT IDENTIFIER ::= { usmMIBObjects 2 }

usmUserSpinLock  OBJECT-TYPE
    SYNTAX       TestAndIncr
    MAX-ACCESS   read-write
    STATUS       current
    DESCRIPTION "An advisory lock used to allow several cooperating
                 Command Generator Applications to coordinate their
                 use of facilities to alter secrets in the
                 usmUserTable.
                "
    ::= { usmUser 1 }

-- The table of valid users for the User-based Security Model ********

usmUserTable     OBJECT-TYPE
    SYNTAX       SEQUENCE OF UsmUserEntry
    MAX-ACCESS   not-accessible
    STATUS       current
    DESCRIPTION "The table of users configured in the SNMP engine's
                 Local Configuration Datastore (LCD).

                 To create a new user (i.e., to instantiate a new
                 conceptual row in this table), it is recommended to
                 follow this procedure:

                   1)  GET(usmUserSpinLock.0) and save in sValue.

                   2)  SET(usmUserSpinLock.0=sValue,
                           usmUserCloneFrom=templateUser,
                           usmUserStatus=createAndWait)
                       You should use a template user to clone from
                       which has the proper auth/priv protocol defined.

                 If the new user is to use privacy:

                   3)  generate the keyChange value based on the secret
                       privKey of the clone-from user and the secret key
                       to be used for the new user. Let us call this
                       pkcValue.
                   4)  GET(usmUserSpinLock.0) and save in sValue.
                   5)  SET(usmUserSpinLock.0=sValue,
                           usmUserPrivKeyChange=pkcValue
                           usmUserPublic=randomValue1)
                   6)  GET(usmUserPulic) and check it has randomValue1.
                       If not, repeat steps 4-6.

                 If the new user will never use privacy:

                   7)  SET(usmUserPrivProtocol=usmNoPrivProtocol)

                 If the new user is to use authentication:

                   8)  generate the keyChange value based on the secret
                       authKey of the clone-from user and the secret key
                       to be used for the new user. Let us call this
                       akcValue.
                   9)  GET(usmUserSpinLock.0) and save in sValue.
                   10) SET(usmUserSpinLock.0=sValue,
                           usmUserAuthKeyChange=akcValue
                           usmUserPublic=randomValue2)
                   11) GET(usmUserPulic) and check it has randomValue2.
                       If not, repeat steps 9-11.

                 If the new user will never use authentication:

                   12) SET(usmUserAuthProtocol=usmNoAuthProtocol)

                 Finally, activate the new user:

                   13) SET(usmUserStatus=active)

                 The new user should now be available and ready to be
                 used for SNMPv3 communication. Note however that access
                 to MIB data must be provided via configuration of the
                 SNMP-VIEW-BASED-ACM-MIB.

                 The use of usmUserSpinlock is to avoid conflicts with
                 another SNMP command generator application which may
                 also be acting on the usmUserTable.
                "
    ::= { usmUser 2 }

usmUserEntry     OBJECT-TYPE
    SYNTAX       UsmUserEntry
    MAX-ACCESS   not-accessible
    STATUS       current
    DESCRIPTION "A user configured in the SNMP engine's Local
                 Configuration Datastore (LCD) for the User-based
                 Security Model.
                "
    INDEX       { usmUserEngineID,
                  usmUserName
                }
    ::= { usmUserTable 1 }

UsmUserEntry ::= SEQUENCE
    {
        usmUserEngineID         SnmpEngineID,
        usmUserName             SnmpAdminString,
        usmUserSecurityName     SnmpAdminString,
        usmUserCloneFrom        RowPointer,
        usmUserAuthProtocol     AutonomousType,
        usmUserAuthKeyChange    KeyChange,
        usmUserOwnAuthKeyChange KeyChange,
        usmUserPrivProtocol     AutonomousType,
        usmUserPrivKeyChange    KeyChange,
        usmUserOwnPrivKeyChange KeyChange,
        usmUserPublic           OCTET STRING,
        usmUserStorageType      StorageType,
        usmUserStatus           RowStatus
    }

usmUserEngineID  OBJECT-TYPE
    SYNTAX       SnmpEngineID
    MAX-ACCESS   not-accessible
    STATUS       current
    DESCRIPTION "An SNMP engine's administratively-unique identifier.

                 In a simple agent, this value is always that agent's
                 own snmpEngineID value.

                 The value can also take the value of the snmpEngineID
                 of a remote SNMP engine with which this user can
                 communicate.

                "
    ::= { usmUserEntry 1 }

usmUserName      OBJECT-TYPE
    SYNTAX       SnmpAdminString (SIZE(1..32))
    MAX-ACCESS   not-accessible
    STATUS       current
    DESCRIPTION "A human readable string representing the name of
                 the user.

                 This is the (User-based Security) Model dependent
                 security ID.
                "
    ::= { usmUserEntry 2 }

usmUserSecurityName OBJECT-TYPE
    SYNTAX       SnmpAdminString
    MAX-ACCESS   read-only
    STATUS       current
    DESCRIPTION "A human readable string representing the user in
                 Security Model independent format.

                 The default transformation of the User-based Security
                 Model dependent security ID to the securityName and
                 vice versa is the identity function so that the
                 securityName is the same as the userName.
                "
    ::= { usmUserEntry 3 }

usmUserCloneFrom OBJECT-TYPE
    SYNTAX       RowPointer
    MAX-ACCESS   read-create
    STATUS       current
    DESCRIPTION "A pointer to another conceptual row in this
                 usmUserTable.  The user in this other conceptual
                 row is called the clone-from user.

                 When a new user is created (i.e., a new conceptual
                 row is instantiated in this table), the privacy and
                 authentication parameters of the new user must be
                 cloned from its clone-from user. These parameters are:
                   - authentication protocol (usmUserAuthProtocol)
                   - privacy protocol (usmUserPrivProtocol)
                 They will be copied regardless of what the current
                 value is.

                 Cloning also causes the initial values of the secret
                 authentication key (authKey) and the secret encryption

                 key (privKey) of the new user to be set to the same
                 values as the corresponding secrets of the clone-from
                 user to allow the KeyChange process to occur as
                 required during user creation.

                 The first time an instance of this object is set by
                 a management operation (either at or after its
                 instantiation), the cloning process is invoked.
                 Subsequent writes are successful but invoke no
                 action to be taken by the receiver.
                 The cloning process fails with an 'inconsistentName'
                 error if the conceptual row representing the
                 clone-from user does not exist or is not in an active
                 state when the cloning process is invoked.

                 When this object is read, the ZeroDotZero OID
                 is returned.
                "
    ::= { usmUserEntry 4 }

usmUserAuthProtocol OBJECT-TYPE
    SYNTAX       AutonomousType
    MAX-ACCESS   read-create
    STATUS       current
    DESCRIPTION "An indication of whether messages sent on behalf of
                 this user to/from the SNMP engine identified by
                 usmUserEngineID, can be authenticated, and if so,
                 the type of authentication protocol which is used.

                 An instance of this object is created concurrently
                 with the creation of any other object instance for
                 the same user (i.e., as part of the processing of
                 the set operation which creates the first object
                 instance in the same conceptual row).

                 If an initial set operation (i.e. at row creation time)
                 tries to set a value for an unknown or unsupported
                 protocol, then a 'wrongValue' error must be returned.

                 The value will be overwritten/set when a set operation
                 is performed on the corresponding instance of
                 usmUserCloneFrom.

                 Once instantiated, the value of such an instance of
                 this object can only be changed via a set operation to
                 the value of the usmNoAuthProtocol.

                 If a set operation tries to change the value of an

                 existing instance of this object to any value other
                 than usmNoAuthProtocol, then an 'inconsistentValue'
                 error must be returned.

                 If a set operation tries to set the value to the
                 usmNoAuthProtocol while the usmUserPrivProtocol value
                 in the same row is not equal to usmNoPrivProtocol,
                 then an 'inconsistentValue' error must be returned.
                 That means that an SNMP command generator application
                 must first ensure that the usmUserPrivProtocol is set
                 to the usmNoPrivProtocol value before it can set
                 the usmUserAuthProtocol value to usmNoAuthProtocol.
                "
    DEFVAL      { usmNoAuthProtocol }
    ::= { usmUserEntry 5 }

usmUserAuthKeyChange OBJECT-TYPE
    SYNTAX       KeyChange   -- typically (SIZE (0 | 32)) for HMACMD5
                             -- typically (SIZE (0 | 40)) for HMACSHA
    MAX-ACCESS   read-create
    STATUS       current
    DESCRIPTION "An object, which when modified, causes the secret
                 authentication key used for messages sent on behalf
                 of this user to/from the SNMP engine identified by
                 usmUserEngineID, to be modified via a one-way
                 function.

                 The associated protocol is the usmUserAuthProtocol.
                 The associated secret key is the user's secret
                 authentication key (authKey). The associated hash
                 algorithm is the algorithm used by the user's
                 usmUserAuthProtocol.

                 When creating a new user, it is an 'inconsistentName'
                 error for a set operation to refer to this object
                 unless it is previously or concurrently initialized
                 through a set operation on the corresponding instance
                 of usmUserCloneFrom.

                 When the value of the corresponding usmUserAuthProtocol
                 is usmNoAuthProtocol, then a set is successful, but
                 effectively is a no-op.

                 When this object is read, the zero-length (empty)
                 string is returned.

                 The recommended way to do a key change is as follows:

                   1) GET(usmUserSpinLock.0) and save in sValue.
                   2) generate the keyChange value based on the old
                      (existing) secret key and the new secret key,
                      let us call this kcValue.

                 If you do the key change on behalf of another user:

                   3) SET(usmUserSpinLock.0=sValue,
                          usmUserAuthKeyChange=kcValue
                          usmUserPublic=randomValue)

                 If you do the key change for yourself:

                   4) SET(usmUserSpinLock.0=sValue,
                          usmUserOwnAuthKeyChange=kcValue
                          usmUserPublic=randomValue)

                 If you get a response with error-status of noError,
                 then the SET succeeded and the new key is active.
                 If you do not get a response, then you can issue a
                 GET(usmUserPublic) and check if the value is equal
                 to the randomValue you did send in the SET. If so, then
                 the key change succeeded and the new key is active
                 (probably the response got lost). If not, then the SET
                 request probably never reached the target and so you
                 can start over with the procedure above.
                "
    DEFVAL      { ''H }    -- the empty string
    ::= { usmUserEntry 6 }

usmUserOwnAuthKeyChange OBJECT-TYPE
    SYNTAX       KeyChange   -- typically (SIZE (0 | 32)) for HMACMD5
                             -- typically (SIZE (0 | 40)) for HMACSHA
    MAX-ACCESS   read-create
    STATUS       current
    DESCRIPTION "Behaves exactly as usmUserAuthKeyChange, with one
                 notable difference: in order for the set operation
                 to succeed, the usmUserName of the operation
                 requester must match the usmUserName that
                 indexes the row which is targeted by this
                 operation.
                 In addition, the USM security model must be
                 used for this operation.

                 The idea here is that access to this column can be
                 public, since it will only allow a user to change
                 his own secret authentication key (authKey).
                 Note that this can only be done once the row is active.

                 When a set is received and the usmUserName of the
                 requester is not the same as the umsUserName that
                 indexes the row which is targeted by this operation,
                 then a 'noAccess' error must be returned.

                 When a set is received and the security model in use
                 is not USM, then a 'noAccess' error must be returned.
                "
    DEFVAL      { ''H }    -- the empty string
    ::= { usmUserEntry 7 }

usmUserPrivProtocol OBJECT-TYPE
    SYNTAX       AutonomousType
    MAX-ACCESS   read-create
    STATUS       current
    DESCRIPTION "An indication of whether messages sent on behalf of
                 this user to/from the SNMP engine identified by
                 usmUserEngineID, can be protected from disclosure,
                 and if so, the type of privacy protocol which is used.

                 An instance of this object is created concurrently
                 with the creation of any other object instance for
                 the same user (i.e., as part of the processing of
                 the set operation which creates the first object
                 instance in the same conceptual row).

                 If an initial set operation (i.e. at row creation time)
                 tries to set a value for an unknown or unsupported
                 protocol, then a 'wrongValue' error must be returned.

                 The value will be overwritten/set when a set operation
                 is performed on the corresponding instance of
                 usmUserCloneFrom.

                 Once instantiated, the value of such an instance of
                 this object can only be changed via a set operation to
                 the value of the usmNoPrivProtocol.

                 If a set operation tries to change the value of an
                 existing instance of this object to any value other
                 than usmNoPrivProtocol, then an 'inconsistentValue'
                 error must be returned.

                 Note that if any privacy protocol is used, then you
                 must also use an authentication protocol. In other
                 words, if usmUserPrivProtocol is set to anything else
                 than usmNoPrivProtocol, then the corresponding instance
                 of usmUserAuthProtocol cannot have a value of

                 usmNoAuthProtocol. If it does, then an
                 'inconsistentValue' error must be returned.
                "
    DEFVAL      { usmNoPrivProtocol }
    ::= { usmUserEntry 8 }

usmUserPrivKeyChange OBJECT-TYPE
    SYNTAX       KeyChange  -- typically (SIZE (0 | 32)) for DES
    MAX-ACCESS   read-create
    STATUS       current
    DESCRIPTION "An object, which when modified, causes the secret
                 encryption key used for messages sent on behalf
                 of this user to/from the SNMP engine identified by
                 usmUserEngineID, to be modified via a one-way
                 function.

                 The associated protocol is the usmUserPrivProtocol.
                 The associated secret key is the user's secret
                 privacy key (privKey). The associated hash
                 algorithm is the algorithm used by the user's
                 usmUserAuthProtocol.

                 When creating a new user, it is an 'inconsistentName'
                 error for a set operation to refer to this object
                 unless it is previously or concurrently initialized
                 through a set operation on the corresponding instance
                 of usmUserCloneFrom.

                 When the value of the corresponding usmUserPrivProtocol
                 is usmNoPrivProtocol, then a set is successful, but
                 effectively is a no-op.

                 When this object is read, the zero-length (empty)
                 string is returned.
                 See the description clause of usmUserAuthKeyChange for
                 a recommended procedure to do a key change.
                "
    DEFVAL      { ''H }    -- the empty string
    ::= { usmUserEntry 9 }

usmUserOwnPrivKeyChange OBJECT-TYPE
    SYNTAX       KeyChange  -- typically (SIZE (0 | 32)) for DES
    MAX-ACCESS   read-create
    STATUS       current
    DESCRIPTION "Behaves exactly as usmUserPrivKeyChange, with one
                 notable difference: in order for the Set operation
                 to succeed, the usmUserName of the operation
                 requester must match the usmUserName that indexes

                 the row which is targeted by this operation.
                 In addition, the USM security model must be
                 used for this operation.

                 The idea here is that access to this column can be
                 public, since it will only allow a user to change
                 his own secret privacy key (privKey).
                 Note that this can only be done once the row is active.

                 When a set is received and the usmUserName of the
                 requester is not the same as the umsUserName that
                 indexes the row which is targeted by this operation,
                 then a 'noAccess' error must be returned.

                 When a set is received and the security model in use
                 is not USM, then a 'noAccess' error must be returned.
                "
    DEFVAL      { ''H }    -- the empty string
    ::= { usmUserEntry 10 }

usmUserPublic    OBJECT-TYPE
    SYNTAX       OCTET STRING (SIZE(0..32))
    MAX-ACCESS   read-create
    STATUS       current
    DESCRIPTION "A publicly-readable value which can be written as part
                 of the procedure for changing a user's secret
                 authentication and/or privacy key, and later read to
                 determine whether the change of the secret was
                 effected.
                "
    DEFVAL      { ''H }  -- the empty string
    ::= { usmUserEntry 11 }

usmUserStorageType OBJECT-TYPE
    SYNTAX       StorageType
    MAX-ACCESS   read-create
    STATUS       current
    DESCRIPTION "The storage type for this conceptual row.

                 Conceptual rows having the value 'permanent' must
                 allow write-access at a minimum to:

                 - usmUserAuthKeyChange, usmUserOwnAuthKeyChange
                   and usmUserPublic for a user who employs
                   authentication, and
                 - usmUserPrivKeyChange, usmUserOwnPrivKeyChange
                   and usmUserPublic for a user who employs
                   privacy.

                 Note that any user who employs authentication or
                 privacy must allow its secret(s) to be updated and
                 thus cannot be 'readOnly'.

                 If an initial set operation tries to set the value to
                 'readOnly' for a user who employs authentication or
                 privacy, then an 'inconsistentValue' error must be
                 returned.  Note that if the value has been previously
                 set (implicit or explicit) to any value, then the rules
                 as defined in the StorageType Textual Convention apply.

                 It is an implementation issue to decide if a SET for
                 a readOnly or permanent row is accepted at all. In some
                 contexts this may make sense, in others it may not. If
                 a SET for a readOnly or permanent row is not accepted
                 at all, then a 'wrongValue' error must be returned.
                "
    DEFVAL      { nonVolatile }
    ::= { usmUserEntry 12 }

usmUserStatus    OBJECT-TYPE
    SYNTAX       RowStatus
    MAX-ACCESS   read-create
    STATUS       current
    DESCRIPTION "The status of this conceptual row.

                 Until instances of all corresponding columns are
                 appropriately configured, the value of the
                 corresponding instance of the usmUserStatus column
                 is 'notReady'.

                 In particular, a newly created row for a user who
                 employs authentication, cannot be made active until the
                 corresponding usmUserCloneFrom and usmUserAuthKeyChange
                 have been set.

                 Further, a newly created row for a user who also
                 employs privacy, cannot be made active until the
                 usmUserPrivKeyChange has been set.

                 The RowStatus TC [RFC2579] requires that this
                 DESCRIPTION clause states under which circumstances
                 other objects in this row can be modified:

                 The value of this object has no effect on whether
                 other objects in this conceptual row can be modified,
                 except for usmUserOwnAuthKeyChange and
                 usmUserOwnPrivKeyChange. For these 2 objects, the

                 value of usmUserStatus MUST be active.
                "
    ::= { usmUserEntry 13 }

-- Conformance Information *******************************************

usmMIBCompliances OBJECT IDENTIFIER ::= { usmMIBConformance 1 }
usmMIBGroups      OBJECT IDENTIFIER ::= { usmMIBConformance 2 }

-- Compliance statements

usmMIBCompliance MODULE-COMPLIANCE
    STATUS       current
    DESCRIPTION "The compliance statement for SNMP engines which
                 implement the SNMP-USER-BASED-SM-MIB.
                "

    MODULE       -- this module
        MANDATORY-GROUPS { usmMIBBasicGroup }

        OBJECT           usmUserAuthProtocol
        MIN-ACCESS       read-only
        DESCRIPTION     "Write access is not required."

        OBJECT           usmUserPrivProtocol
        MIN-ACCESS       read-only
        DESCRIPTION     "Write access is not required."

    ::= { usmMIBCompliances 1 }

-- Units of compliance
usmMIBBasicGroup OBJECT-GROUP
    OBJECTS     {
                  usmStatsUnsupportedSecLevels,
                  usmStatsNotInTimeWindows,
                  usmStatsUnknownUserNames,
                  usmStatsUnknownEngineIDs,
                  usmStatsWrongDigests,
                  usmStatsDecryptionErrors,
                  usmUserSpinLock,
                  usmUserSecurityName,
                  usmUserCloneFrom,
                  usmUserAuthProtocol,
                  usmUserAuthKeyChange,
                  usmUserOwnAuthKeyChange,
                  usmUserPrivProtocol,
                  usmUserPrivKeyChange,
                  usmUserOwnPrivKeyChange,
                  usmUserPublic,
                  usmUserStorageType,
                  usmUserStatus
                }
    STATUS       current
    DESCRIPTION "A collection of objects providing for configuration
                 of an SNMP engine which implements the SNMP
                 User-based Security Model.
                "
    ::= { usmMIBGroups 1 }

END

6.安全机制

HMAC-MD5

HMAC-MD5-96 Authentication Protocol是一种基于HMAC和MD5算法的认证协议,它用于确保数据包的来源和完整性。以下是其实现的基本原理:

  1. 密钥选择:HMAC-MD5-96认证协议假设认证密钥的选择由调用者完成,并且调用者将要使用的密钥传递给认证模块。这个密钥的长度必须为16个八进制数。

  2. 消息处理:HMAC-MD5-96认证协议处理接收到的SNMP消息。具体的处理过程包括:生成消息认证码(MAC),验证消息的完整性和来源,以及处理可能的错误。

  3. 消息认证:HMAC-MD5-96认证协议使用MD5算法生成一个128位的认证值。这个128位的值可以被截断,但是至少需要保留96位,以满足安全要求。

  4. 消息发送和接收:在发送消息时,将截断的认证值存储在认证字段中。在接收消息时,计算整个128位的认证值,并将其与存储在认证字段中的值进行比较。如果两者相同,则认证成功2。

  5. 密钥管理:HMAC-MD5-96认证协议是一种密钥算法。为了提供数据来源认证,密钥分发机制必须确保分配了唯一的密钥,并且只将它们分发给参与通信的方。

  6. 安全考虑:HMAC-MD5-96认证协议的安全性基于HMAC的强度,以及MD5的一定程度的强度。虽然MD5在最初被认为具有很强的碰撞抵抗性,但是最近的研究发现它实际上并不具有很强的碰撞抵抗性。因此,对于HMAC-MD5-96认证协议的安全性评估,需要考虑MD5的这个特性。

HMAC-SHA1

HMAC-SHA-96 Authentication Protocol是一种基于HMAC和SHA算法的认证协议,它用于确保数据包的来源和完整性。以下是其实现的基本原理:

  1. 密钥选择:HMAC-SHA-96认证协议假设认证密钥的选择由调用者完成,并且调用者将要使用的密钥传递给认证模块。这个密钥的长度必须为20个八进制数。

  2. 消息处理:HMAC-SHA-96认证协议处理接收到的SNMP消息。具体的处理过程包括:生成消息认证码(MAC),验证消息的完整性和来源,以及处理可能的错误。

  3. 消息认证:HMAC-SHA-96认证协议使用SHA算法生成一个160位的认证值。这个160位的值可以被截断,但是至少需要保留96位,以满足安全要求。

  4. 消息发送和接收:在发送消息时,将截断的认证值存储在认证字段中。在接收消息时,计算整个160位的认证值,并将其与存储在认证字段中的值进行比较。如果两者相同,则认证成功。。

  5. 密钥管理:HMAC-SHA-96认证协议是一种密钥算法。为了提供数据来源认证,密钥分发机制必须确保分配了唯一的密钥,并且只将它们分发给参与通信的方。

  6. 安全考虑:HMAC-SHA-96认证协议的安全性基于HMAC的强度,以及SHA的一定程度的强度。虽然SHA在最初被认为具有很强的碰撞抵抗性,但是最近的研究发现它实际上并不具有很强的碰撞抵抗性。因此,对于HMAC-SHA-96认证协议的安全性评估,需要考虑SHA的这个特性。

CBC-DES

CBC-DES Symmetric Encryption Protocol是RFC3414中定义的一种用户基础安全模型的第一种隐私协议。这个协议使用DES(数据加密标准)进行对称加密,以确保数据的机密性。以下是其工作流程的详细描述:

  1. 选择加密算法:为了支持数据机密性,需要一个加密算法。适当的消息部分在传输之前需要被加密。用户基础安全模型规定,需要加密的部分是scopedPDU。

  2. 创建加密和解密密钥:一个秘密值和一个时效值被用来创建加密和解密密钥以及初始化向量。这个秘密值被所有被授权在代表适当用户的名义发送消息的SNMP引擎共享。

  3. 对称加密协议:这个协议提供了对数据机密性的支持。被指定的SNMP消息部分被加密并作为发送给接收者的消息的一部分包含在内。

  4. DES密钥和初始化向量:DES密钥和初始化向量的生成方法在RFC3414中有详细的描述。这个过程涉及到秘密值、时效值和用户的私钥。

  5. 数据加密:指定的SNMP消息部分被加密并作为发送给接收者的消息的一部分包含在内。

  6. 数据解密:在接收消息时,使用相同的DES密钥和初始化向量对接收到的加密数据进行解密。