用于测试目的的最快公钥算法

信息安全 gnupg
2021-08-27 07:49:24

作为自动化测试套件的一部分,我需要运行很多gpg --encrypt流程gpg --decrypt

为了使每次调用都gpg --encrypt更快gpg --decrypt,我想使用一个非常快的公钥算法。

我知道最快的密码也是那些提供最弱安全性的密码,尤其是在小密钥大小时。然而,在这种情况下,安全性并不是重要问题:无密码密钥甚至作为测试套件的一部分公开发布。

作为参考,这是我的 GnuPG 版本支持的:

Pubkey: RSA, ELG, DSA
Cipher: 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128, 
        CAMELLIA192, CAMELLIA256
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

回顾一下,GnuPG 中最快的算法和密钥长度组合是什么?

1个回答

这将因机器和 GPG 二进制文件而异。机器是否提供 AES-NI 指令,您的 GPG 二进制文件是否使用它们,是否使用 64 位操作,您的二进制文件是否可用和使用 XOP 或 AVX 指令等。

只有一个答案:在您的特定设置上进行基准测试!

Daniel Kahn Gillmor 在 2010 年的 gnupg 用户列表中发布了这样一个基准脚本,其中自然包括一个 SHA1 和和一个签名。

请注意,输出来自 Unix time 命令,格式为 +,以秒为单位。

如果您想要不同的东西,请修改脚本!

#!/bin/sh

# Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
# Date: Tue, 28 Sep 2010 14:25:19 -0400

# This script produces some roughly-formatted OpenPGP performance data
# against different algorithms and keysizes


set -e

REPEAT=100
ASYM_ALGOS="RSA DSA"
KEY_SIZES="1024 2048 3072 4096"
DIGESTS="SHA1 SHA224 SHA256 SHA384 SHA512"
CIPHERS="3DES AES AES192 AES256"

if gpg --debug-quick-random --version >/dev/null 2>/dev/null ; then
    QUICKRANDOM=--debug-quick-random
elif gpg --quick-random --version >/dev/null 2>/dev/null ; then
    QUICKRANDOM=--quick-random
else
    printf "don't know how to set quick random number generation"
    exit 2
fi

encalgo() {
    if [ "$1" = "DSA" ]; then
    printf "ELG-E"
    else
    printf "%s" "$1"
    fi
}

describe_system() {
    # FIXME: this is fairly Linux-specific.  it'd be better to use
    # something more generic to get info about the CPU and RAM
    # available:
    cat /proc/cpuinfo 2>&1 || :
    free 2>&1 || :
    uname -a
    gpg --version
}

# quick key creation:
setup() {
    rm -f testmsg
    for rep in $(seq 1 25) ; do
    echo "this is a test message for benchmarking OpenPGP signature validation times." >> testmsg
    done
    for algo in $ASYM_ALGOS; do
    for size in $KEY_SIZES; do
        if [ "$algo" = "DSA" ] && [ "$size" -gt 3072 ]; then
        # gpg can't do DSA > 3072 bits
        continue
        fi
        mkdir -m 0700 -p ${algo}-${size}
        if printf 'Key-Type: %s
Key-Length: %s
Key-Usage: sign
Subkey-Type: %s
Subkey-Length: %s
Subkey-Usage: encrypt
Name-Real: OpenPGP Benchmark Key %s %s bits
Name-Comment: DO NOT USE!
' "$algo" "$size" $(encalgo "$algo") "$size" "$algo" "$size" | GNUPGHOME=${algo}-${size} gpg $QUICKRANDOM --batch --gen-key ; then
        for digest in $DIGESTS; do
            output=${algo}-${size}/testmsg.${algo}-${size}-${digest}.asc
            if ! GNUPGHOME=${algo}-${size} gpg --digest-algo "$digest" --clearsign < testmsg > ${output} ; then
            rm -f ${output}
            fi
        done

        for cipher in $CIPHERS; do
            output=${algo}-${size}/testmsg.${algo}-${size}-${cipher}.asc
            if ! GNUPGHOME=${algo}-${size} gpg --armor --cipher-algo "$cipher" --encrypt -r 'Benchmark' < testmsg > ${output} ; then
            rm -f ${output}
            fi
        done
        else
        rm -rf ${algo}-${size}
        fi
    done
    done
}


signing() {
    for algo in $ASYM_ALGOS ; do
    printf '%s Signing (x%d)\n' $algo $REPEAT
    for length in 'digest:' $KEY_SIZES; do
        if [ -d "${algo}-${length}" ] || [ "$length" = 'digest:' ]; then
        printf '%s\t' "$length"
        for digest in $DIGESTS; do
            if [ "$length" = 'digest:' ]; then
            printf '%s\t' "$digest"
            else
            for x in ${algo}-${length}/*; do
                cat < "$x" > /dev/null
            done
            targfile=${algo}-${length}/testmsg.${algo}-${length}-${digest}.asc
            if [ -e $targfile ]; then
                stats=$(bash -c "time -p for seq in $(seq 1 $REPEAT | tr '\n' ' '); do
GNUPGHOME=${algo}-${length} gpg --digest-algo $digest --sign >/dev/null 2>/dev/null < ./testmsg
done" 2>&1)
                printf '%s+%s\t' $(printf "%s" "$stats" | grep ^user | cut -f2 -d' ') $(printf "%s" "$stats" | grep ^sys | cut -f2 -d' ')
            else
                printf 'X\t'
            fi
            fi
        done
        printf '\n'
        fi
    done
    done
}

verifying() { 
    for algo in $ASYM_ALGOS ; do
    printf '%s Verifying (x%d)\n' $algo $REPEAT
    for length in 'digest:' $KEY_SIZES; do
        if [ -d "${algo}-${length}" ] || [ "$length" = 'digest:' ]; then
        printf '%s\t' "$length"
        for digest in $DIGESTS; do
            if [ "$length" = 'digest:' ]; then
            printf '%s\t' "$digest"
            else
            for x in ${algo}-${length}/*; do
                cat < "$x" > /dev/null
            done
            targfile=${algo}-${length}/testmsg.${algo}-${length}-${digest}.asc
            if [ -e $targfile ]; then
                stats=$(bash -c "time -p for seq in $(seq 1 $REPEAT | tr '\n' ' '); do
GNUPGHOME=${algo}-${length} gpg --verify >/dev/null 2>/dev/null < $targfile
done" 2>&1)
                printf '%s+%s\t' $(printf "%s" "$stats" | grep ^user | cut -f2 -d' ') $(printf "%s" "$stats" | grep ^sys | cut -f2 -d' ')
            else
                printf 'X\t'
            fi
            fi
        done
        printf '\n'
        fi
    done
    done
}


encrypting() {
    for algo in $ASYM_ALGOS ; do
    printf '%s Encrypting (x%s)\n' $(encalgo "$algo") $REPEAT
    for length in 'cipher:' $KEY_SIZES; do
        if [ -d "${algo}-${length}" ] || [ "$length" = 'cipher:' ]; then
        printf '%s\t' "$length"
        for cipher in $CIPHERS; do
            if [ "$length" = 'cipher:' ]; then
            printf '%s\t' "$cipher"
            else
            for x in ${algo}-${length}/*; do
                cat < "$x" > /dev/null
            done
            targfile=${algo}-${length}/testmsg.${algo}-${length}-${cipher}.asc
            if [ -e $targfile ]; then
                stats=$(bash -c "time -p for seq in $(seq 1 $REPEAT | tr '\n' ' '); do
GNUPGHOME=${algo}-${length} gpg --cipher-algo $cipher --encrypt -r Benchmark >/dev/null 2>/dev/null < ./testmsg
done" 2>&1)
                printf '%s+%s\t' $(printf "%s" "$stats" | grep ^user | cut -f2 -d' ') $(printf "%s" "$stats" | grep ^sys | cut -f2 -d' ')
            else
                printf 'X\t'
            fi
            fi
        done
        printf '\n'
        fi
    done
    done
}


decrypting() {
    for algo in $ASYM_ALGOS ; do
    printf '%s Decrypting (x%s)\n' $(encalgo "$algo") $REPEAT
    for length in 'cipher:' $KEY_SIZES; do
        if [ -d "${algo}-${length}" ] || [ "$length" = 'cipher:' ]; then
        printf '%s\t' "$length"
        for cipher in $CIPHERS; do
            if [ "$length" = 'cipher:' ]; then
            printf '%s\t' "$cipher"
            else
            for x in ${algo}-${length}/*; do
                cat < "$x" > /dev/null
            done
            targfile=${algo}-${length}/testmsg.${algo}-${length}-${cipher}.asc
            if [ -e $targfile ]; then
                stats=$(bash -c "time -p for seq in $(seq 1 $REPEAT | tr '\n' ' '); do
GNUPGHOME=${algo}-${length} gpg --decrypt >/dev/null 2>/dev/null < $targfile
done" 2>&1)
                printf '%s+%s\t' $(printf "%s" "$stats" | grep ^user | cut -f2 -d' ') $(printf "%s" "$stats" | grep ^sys | cut -f2 -d' ')
            else
                printf 'X\t'
            fi
            fi
        done
        printf '\n'
        fi
    done
    done
}


run() {
    WORKDIR=$(mktemp -d "${TMPDIR:-/tmp}/openpgp-benchmark.XXXXXX")
    OUTPUT=$(mktemp "$(pwd)/openpgp-benchmark.$(date +%F_%T | tr ':' '-').XXXXXX")
    printf 'Working in %s...\n' "$WORKDIR"
    cd "$WORKDIR"
    ( describe_system
        setup
        signing
        verifying
        encrypting 
        decrypting ) | tee "$OUTPUT"
    printf 'log written to %s...\nPlease mail back to Daniel Kahn Gillmor <dkg@fifthhorseman.net>.\n' "$OUTPUT"
}

action="$1"
if [ "x$action" = "x" ]; then
    action=run
fi

case "$action" in
    setup|describe_system|signing|verifying|encrypting|run)
        "$action"
        ;;
    *)
        echo "Usage: $0 [setup|describe_system|signing|verifying|encrypting|run]  " >&2
        exit 2
        ;;
esac