首页 > 解决方案 > C++ 中的短消息 AES 性能

问题描述

我正在尝试以高速方式执行 AES。当我使用以下命令执行 openssl speed test 时,我得到以下结果:

    $ openssl speed -elapsed -evp aes-128-cbc
You have chosen to measure elapsed time instead of user CPU time.
Doing aes-128-cbc for 3s on 16 size blocks: 224201744 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 64 size blocks: 62982851 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 256 size blocks: 16102515 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 1024 size blocks: 4052200 aes-128-cbc's in 3.00s
Doing aes-128-cbc for 3s on 8192 size blocks: 510962 aes-128-cbc's in 3.00s
OpenSSL 1.0.2n  7 Dec 2017
built on: reproducible build, date unspecified
options:bn(64,64) rc4(16x,int) des(idx,cisc,16,int) aes(partial) idea(int) blowfish(idx) 
compiler: gcc -I. -I.. -I../include  -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -DL_ENDIAN -O3 -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DRC4_ASM -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
aes-128-cbc    1195742.63k  1343634.15k  1374081.28k  1383150.93k  1395266.90k

这意味着 128 位块的每个 AES 加密的速度应该是 1.32 ns。但是当我执行以下使用 openssl 和 EVP 的 C++ 代码时,性能变为 217 ns:

#include <stdio.h>
#include <openssl/evp.h>
#include <chrono>
#include <iostream>
using namespace std;
int main()
{
    EVP_CIPHER_CTX ctx;
    unsigned char key[16] = {0};
    unsigned char iv[16] = {0};
    unsigned char in[16] = {0};
    unsigned char out[16]; /* at least one block longer than in[] */
    int outlen1, outlen2;
    std::chrono::time_point<std::chrono::high_resolution_clock> m_beg = std::chrono::high_resolution_clock::now();
    for(int z=0;z<10000;z++){
    EVP_EncryptInit(&ctx, EVP_aes_128_cbc(), key, iv);
    EVP_EncryptUpdate(&ctx, out, &outlen1, in, sizeof(in));
    EVP_EncryptFinal(&ctx, out + outlen1, &outlen2);
    }
    double t = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - m_beg).count();
    cout<<t<<endl;
    printf("ciphertext length: %d\n", outlen1 + outlen2);

    return 0;
}

有谁知道问题出在哪里?

这是我的发布制作文件:

# Environment
MKDIR=mkdir
CP=cp
GREP=grep
NM=nm
CCADMIN=CCadmin
RANLIB=ranlib
CC=gcc
CCC=g++
CXX=g++
FC=g++
AS=as

# Macros
CND_PLATFORM=GNU-Linux
CND_DLIB_EXT=so
CND_CONF=Release
CND_DISTDIR=dist
CND_BUILDDIR=build

# Include project Makefile
include Makefile

# Object Directory
OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}

# Object Files
OBJECTFILES= \
    ${OBJECTDIR}/main.o


# C Compiler Flags
CFLAGS=

# CC Compiler Flags
CCFLAGS=
CXXFLAGS=

# Fortran Compiler Flags
FFLAGS=

# Assembler Flags
ASFLAGS=

# Link Libraries and Options
LDLIBSOPTIONS=

# Build Targets
.build-conf: ${BUILD_SUBPROJECTS}
    "${MAKE}"  -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/aes_ni_test

${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/aes_ni_test: ${OBJECTFILES}
    ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
    ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/aes_ni_test ${OBJECTFILES} ${LDLIBSOPTIONS} -lcrypto

${OBJECTDIR}/main.o: main.cpp
    ${MKDIR} -p ${OBJECTDIR}
    ${RM} "$@.d"
    $(COMPILE.cc) -O3 -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/main.o main.cpp

# Subprojects
.build-subprojects:

# Clean Targets
.clean-conf: ${CLEAN_SUBPROJECTS}
    ${RM} -r ${CND_BUILDDIR}/${CND_CONF}

# Subprojects
.clean-subprojects:

# Enable dependency checking
.dep.inc: .depcheck-impl

include .dep.inc

标签: c++linuxencryptionopensslaes

解决方案


原因是 c++ 代码中 AES 的 INIT 和 FINAL 部分。OPENSSL 命令不会对每次加密都执行它。因此,它的性能要高得多。


推荐阅读