You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确定OpenSSL HMAC摘要的默认长度?

获取OpenSSL HMAC摘要比特数的优化方案

需求说明

需要获取OpenSSL支持的HMAC摘要生成的比特数(或十六进制位数),原通过自定义bash函数实现,执行echo $(sslmacbits sha1)可得到结果10,但希望找到更高效的实现方式。

原实现思路

原脚本通过生成实际摘要、提取十六进制结果、计算长度转换为目标数值,同时处理了SHAKE系列可变长度摘要的特殊情况,还包含OpenSSL安装检查、摘要有效性验证逻辑。

优化实现方案

方案1:利用摘要固有长度映射表(高效无依赖)

大部分摘要算法的输出长度是固定的,直接构建映射表返回结果,SHAKE系列单独处理,避免生成实际摘要的开销:

#!/bin/bash
if [[ -z "${__hmacsslmacbits_opt}" ]]; then
    export __hmacsslmacbits_opt=1

    function sslmacbits() {
        local dgstname=$1
        # 固定摘要算法的比特数映射表(若需原脚本输出的"字符数/4"结果,可将数值改为对应值,如sha1改为10)
        declare -A digest_bits=(
            ["md5"]=128 ["sha1"]=160 ["sha224"]=224 ["sha256"]=256
            ["sha384"]=384 ["sha512"]=512 ["sha512-224"]=224 ["sha512-256"]=256
            ["sha3-224"]=224 ["sha3-256"]=256 ["sha3-384"]=384 ["sha3-512"]=512
            ["blake2b512"]=512 ["blake2s256"]=256 ["ripemd160"]=160
        )

        # 参数检查
        if [[ $# -ne 1 ]]; then
            echo "用法: sslmacbits <摘要算法名>" >&2
            return 1
        fi

        # 检查OpenSSL是否安装
        if ! command -v openssl &> /dev/null; then
            echo "未找到openssl,尝试自动安装..." >&2
            sudo apt-get install -y openssl || return 3
        fi

        # 检查摘要算法是否存在
        if ! openssl list -digest-commands | grep -q "^${dgstname}$"; then
            echo "指定的摘要算法${dgstname}未在当前OpenSSL中支持" >&2
            return 2
        fi

        # 处理可变长度的SHAKE系列
        case $dgstname in
            shake128)
                # 按原脚本逻辑使用32字节(256比特)作为默认长度,若需原输出则改为8
                echo 256
                ;;
            shake256)
                # 按原脚本逻辑使用64字节(512比特)作为默认长度,若需原输出则改为16
                echo 512
                ;;
            *)
                # 从映射表获取固定长度
                if [[ -n "${digest_bits[$dgstname]}" ]]; then
                    echo "${digest_bits[$dgstname]}"
                else
                    # 兼容未知固定长度算法, fallback到原方法
                    local digest=$((openssl ${dgstname} -hex <<<"Hello World") | awk -F'= ' '{print $2}')
                    # 若需保持原脚本的"字符数/4"输出,改为echo $(( ${#digest} / 4 ))
                    echo $(( ${#digest} * 4 ))
                fi
                ;;
        esac
    }
    export -f sslmacbits
fi

方案2:简化原脚本的执行流程

如果不想用映射表,可简化原脚本的摘要提取逻辑,用awk直接分割结果,减少字符串处理复杂度:

#!/bin/bash
if [[ -z "${__hmacsslmacbits_simple}" ]]; then
    export __hmacsslmacbits_simple=1

    function sslmacbits() {
        local CHEXBITS=4
        local dgstname=$1

        if [[ $# -ne 1 ]]; then
            echo "用法: sslmacbits <摘要算法名>" >&2
            return 1
        fi

        if ! command -v openssl &> /dev/null; then
            echo "未找到openssl,尝试自动安装..." >&2
            sudo apt-get install -y openssl || return 3
        fi

        if ! openssl list -digest-commands | grep -q "^${dgstname}$"; then
            echo "指定的摘要算法${dgstname}未在当前OpenSSL中支持" >&2
            return 2
        fi

        local chkopenssl="openssl ${dgstname} -hex"
        case $dgstname in
            shake128) chkopenssl="${chkopenssl} -xoflen 32" ;;
            shake256) chkopenssl="${chkopenssl} -xoflen 64" ;;
        esac

        # 用awk直接提取十六进制结果,避免复杂的字符串切割
        local digesthex=$($chkopenssl <<<"Hello World" | awk -F'= ' '{print $2}')
        # 若需实际比特数,改为echo $(( ${#digesthex} * CHEXBITS ))
        echo $(( ${#digesthex} / CHEXBITS ))
    }
    export -f sslmacbits
fi

优化点说明

  1. 性能提升:方案1通过映射表直接返回固定长度,无需生成实际摘要,执行速度更快;
  2. 代码简化:方案2用awk替代原脚本的字符串切割逻辑,代码更简洁易读;
  3. 鲁棒性优化:统一使用command -v检查命令存在性,比which更可靠;用grep -q "^${dgstname}$"精确匹配摘要命令,避免部分匹配误判;用返回错误码替代exit,避免source引入后退出整个shell;
  4. 逻辑修正提示:原脚本中比特数计算逻辑存在错误,正确的比特数应为十六进制字符数乘以4(每个十六进制字符对应4比特)。若需保持原输出(十六进制字符数/4),可保留原计算式;若需获取实际比特数,调整计算式即可。

内容的提问来源于stack exchange,提问作者sailnfool

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 19:13:11