十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Authelia 深入解析:authelia storage encryption rotate hmac 命令与 HMAC 密钥轮换机制

Authelia 深入解析:authelia storage encryption rotate hmac 命令与 HMAC 密钥轮换机制 Authelia 深入解析authelia storage encryption rotate hmac 命令与 HMAC 密钥轮换机制【免费下载链接】autheliaThe Single Sign-On Multi-Factor portal for web apps. OpenID Certified™ and Post-Quantum Cryptography Ready.项目地址: https://gitcode.com/GitHub_Trending/au/authelia本文围绕 Authelia CLI 中的authelia storage encryption rotate hmac子命令展开先给出该命令的完整参考信息Synopsis、Options 及从父命令继承的全量选项再结合源码剖析其命令树结构、otc/otp两个真正执行轮换的子命令、交互式确认与强制跳过机制以及底层SchemaEncryptionRotateHMACKey在 SQLite/MySQL/PostgreSQL 之上的事务实现。读完本文你将能够安全地在生产环境中完成 HMAC 密钥轮换并理解被保护表one_time_code、totp_history为何必须随之清空。命令定位与 Synopsisauthelia storage encryption rotate hmac属于authelia storage encryption命令族下的HMAC 密钥轮换分组命令。官方文档给出的 Synopsis 为Rotate HMAC keys. This subcommand allows rotation of HMAC keys used for various purposes. 轮换 HMAC 密钥。该子命令允许轮换用于各种用途的 HMAC 密钥。需要特别注意的一点是hmac这一层本身是一个“分组”命令不带任何可执行逻辑。从 internal/commands/storage.go 中的命令定义可以确认这一点——newStorageEncryptRotateHMACCmd只设置了Use、Short、Long、Example而没有RunE其唯一职责是挂载两个子命令func newStorageEncryptRotateHMACCmd(ctx *CmdCtx) (cmd *cobra.Command) { cmd cobra.Command{ Use: hmac, Short: cmdAutheliaStorageEncryptionRotateHMACShort, // ... } cmd.AddCommand( newStorageEncryptRotateHMACOTPCmd(ctx), // otp newStorageEncryptRotateHMACOTCCmd(ctx), // otc ) return cmd }真正会修改数据库的是两个叶子子命令子命令用途对应表HMAC 算法密钥长度authelia storage encryption rotate hmac otc轮换一次码one-time codeOTC的 HMAC 密钥one_time_codeHMAC-SHA512sha512.BlockSize64 字节authelia storage encryption rotate hmac otp轮换 TOTP 历史记录OTP的 HMAC 密钥totp_historyHMAC-SHA256sha256.BlockSize32 字节文档中给出的基础示例为authelia storage encryption rotate hmac --help而 internal/commands/const.go 中为两个叶子子命令提供了更贴近实操的完整示例authelia storage encryption rotate hmac otp --config config.yml authelia storage encryption rotate hmac otp --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.address tcp://postgres:5432 --postgres.password autheliapw authelia storage encryption rotate hmac otc --config config.yml authelia storage encryption rotate hmac otc --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.address tcp://postgres:5432 --postgres.password autheliapw也就是说可以完全脱离配置文件仅靠命令行参数加密密钥 数据库连接信息直连目标库执行轮换。Options 与从父命令继承的选项hmac分组命令自身只提供-h, --help help for hmac真正的执行选项来自父命令链的继承。原文档列出的继承选项必须完整保留以下是全量清单-c, --config strings configuration files or directories to load, for more information run authelia -h authelia config (default [configuration.yml]) --config.experimental.filters strings list of filters to apply to all configuration files, for more information run authelia -h authelia filters --encryption-key string the storage encryption key to use --mysql.address string the MySQL server address (default tcp://127.0.0.1:3306) --mysql.database string the MySQL database name (default authelia) --mysql.password string the MySQL password --mysql.username string the MySQL username (default authelia) --postgres.address string the PostgreSQL server address (default tcp://127.0.0.1:5432) --postgres.database string the PostgreSQL database name (default authelia) --postgres.password string the PostgreSQL password --postgres.schema string the PostgreSQL schema name (default public) --postgres.username string the PostgreSQL username (default authelia) --sqlite.path string the SQLite database path这些持久persistent标志在 internal/commands/storage.go 的newStorageCmd中统一定义并通过 cobra 的PersistentFlags()沿命令树向下继承。结合 ConfigStorageCommandLineConfigRunE 中的映射表可以看到每个标志最终写回的配置路径命令行标志映射到配置路径说明--encryption-keystorage.encryption_key存储加密密钥用于解密数据库中密文与 HMAC 密钥本身--sqlite.pathstorage.local.pathSQLite 数据库文件路径--mysql.addressstorage.mysql.address默认tcp://127.0.0.1:3306--mysql.databasestorage.mysql.database默认authelia--mysql.usernamestorage.mysql.username默认authelia--mysql.passwordstorage.mysql.password无默认值--postgres.addressstorage.postgres.address默认tcp://127.0.0.1:5432--postgres.databasestorage.postgres.database默认authelia--postgres.schemastorage.postgres.schema默认public--postgres.usernamestorage.postgres.username默认authelia--postgres.passwordstorage.postgres.password无默认值此外每个叶子子命令otc、otp还自带一个本地标志见 internal/commands/storage.go-f, --force force the rotation without confirmation即不带--force时命令会进入交互式确认流程带上后跳过确认直接执行适合脚本化场景。执行前的准备链条同样由源码保证storage命令的PersistentPreRunE依次执行ConfigStorageCommandLineConfigRunE标志回填配置→HelperConfigLoadRunE加载配置→ConfigValidateStorageRunE校验 storage/totp 配置→LoadProvidersStorageRunE建立存储 Provider 连接。只有全部成功后otc/otp的RunE才会被调用。执行流程源码解析从确认提示到事务提交叶子子命令的RunE均为 StorageSchemaEncryptionRotateRunE其核心逻辑分三步前置检查ctx.CheckSchema()确认数据库具备 Authelia 存储 schema否则直接报错退出。表名映射按cmd.Use判断要操作的目标——otc对应one_time_code表otp对应totp_history表var table string switch cmd.Use { case otc: table one_time_code case otp: table totp_history } return runStorageSchemaEncryptionRotateKey(ctx, cmd.OutOrStdout(), ctx.providers.StorageProvider, table, cmd.Use, force)版本校验 确认 轮换runStorageSchemaEncryptionRotateKey要求 schema 版本至少为 1schema version must be at least version 1 to rotate keys在未指定--force时弹出破坏性操作确认This will rotate the HMAC key and truncate the one_time_code table, this is not reversible, type ROTATE and press return to continue:只有输入ROTATE才会继续否则报错cancelling key rotation due to user not accepting data destruction。确认通过后调用store.SchemaEncryptionRotateHMACKey(ctx, name)成功后输出Completed the otc key rotation successfully and cleanly truncated the one_time_code table.底层实现SchemaEncryptionRotateHMACKey 的事务细节真正落库的逻辑位于 SQLProvider.SchemaEncryptionRotateHMACKey它在一个数据库事务内完成“生成新密钥 → 替换存储 → 清空受保护表”三个动作// SchemaEncryptionRotateHMACKey rotates the HMAC key with the given name, truncating the table it protects. func (p *SQLProvider) SchemaEncryptionRotateHMACKey(ctx context.Context, name string) (err error) { var ( size int table string desc string ) switch name { case hmacNameOneTimeCode: size, table, desc sha512.BlockSize, tableOneTimeCode, one time-codes case hmacNameOneTimePassword: size, table, desc sha256.BlockSize, tableTOTPHistory, totp history default: return fmt.Errorf(unknown key name %s, name) } var tx SQLXTx if tx, err p.db.Beginx(); err ! nil { ... } if _, err p.setCrypographyKey(ctx, tx, keyTypeCryptographyHMAC, name, size, true); err ! nil { // 回滚 } if err p.truncate(ctx, tx, table); err ! nil { // 回滚 } if err tx.Commit(); err ! nil { ... } return nil }几个关键实现事实密钥名称与存储位置常量定义在 internal/storage/const.go——hmacNameOneTimeCode otc、hmacNameOneTimePassword otpHMAC 密钥统一命名为hmac_key_%s即hmac_key_otc、hmac_key_otp。setCrypographyKey先用crypto/rand生成指定长度的随机密钥再经setEncryptionValue用 storage 加密密钥--encryption-key对应的密钥加密后 upsert 到encryption表——这意味着轮换命令必须持有正确的encryption_key否则启动时根本无法解密出任何密钥。事务原子性新密钥写入与表清空在同一事务中提交任一步骤失败都会显式Rollback不会出现“密钥已换但旧表数据仍在”或“表已清空但密钥未换”的中间状态。为何必须 truncateHMAC 签名是在写入时计算的密钥一旦更换旧行中的签名在新密钥下立即失效无法再被验证因此被保护表必须清空。对otc而言影响的是尚未消费的 one-time code例如 OAuth2 设备流程/授权码交换类的一次性令牌对otp而言影响的是 TOTP 历史防重放记录——清空后旧密钥周期内尚未过期的 TOTP 验证码理论上存在一次重放窗口这是轮换时应当评估的代价。密钥读取是自动的正常运行时getHMACOneTimeCode/getHMACOneTimePassword会在首次取不到密钥时自动生成并落库getHMACKey中处理sql.ErrNoRows分支所以只有在你“主动想换密钥”时才需要本命令。被保护的数据OTC 与 OTP 的签名场景理解为什么要轮换这两个 HMAC 密钥最好看它们的实际用途。从 internal/storage/sql_provider.go 可以确认两个签名函数的调用点// OTC对 用户名 IP 意图 明文码 做 HMAC-SHA512 code.Signature p.otcHMACSignature([]byte(code.Username), code.IssuedIP.IP, []byte(code.Intent), code.Code) // OTP对 TOTP step 用户名 做 HMAC-SHA256 signature : p.otpHMACSignature([]byte(strconv.FormatUint(step, 10)), []byte(username))otcHMACSignatureHMAC-SHA512密钥p.keys.otcHMAC为每次落库的一次码生成签名验证时重算比对防止库内数据被篡改后被当作合法一次码使用otpHMACSignatureHMAC-SHA256密钥p.keys.otpHMAC为 TOTP 历史行生成签名配合 step 记录实现 TOTP 防重放。两者的 HMAC 密钥虽然本身存放在encryption表里并受 storage 加密密钥保护但如果库被拖走且加密密钥泄露攻击者即可伪造合法签名数据——这正是提供 HMAC 密钥轮换能力的安全动机定期轮换可在不重建数据库的前提下切断旧密钥的滥用路径。实践建议与相关命令先验证密钥再动手执行轮换前可先运行authelia storage encryption check对应 StorageSchemaEncryptionCheckRunE确认当前--encryption-key与库中数据匹配输出SUCCESS/FAILURE避免拿错密钥连接生产库。轮换不可逆两个子命令都会截断对应表且无法恢复务必使用--force前先演练非交互环境下必须显式传-f否则命令会阻塞在确认提示处。schema 版本要求目标库 schema 版本必须 ≥ 1否则命令直接报错退出。与 change-key 的区别authelia storage encryption change-key改变的是数据库整体加密密钥需要逐行解密再重加密全部密文表而rotate hmac只替换 HMAC 密钥并清空两张签名表动作更轻、影响面更明确。相关参考文档同目录下的 CLI 参考页authelia storage encryption rotateauthelia storage encryption rotate hmac otcauthelia storage encryption rotate hmac otp存储加密密钥配置项config.template.yml 中storage.encryption_key要求至少 20 字符的随机字符串【免费下载链接】autheliaThe Single Sign-On Multi-Factor portal for web apps. OpenID Certified™ and Post-Quantum Cryptography Ready.项目地址: https://gitcode.com/GitHub_Trending/au/authelia创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表