목적

AES 대칭키 알고리즘은 아키텍처에서 AES-NI와 같은 HW 가속 instruction set을 제공하기도 한다.

라이브러리에서 AES 가속을 지원한다면 프로그램의 수행속도를 줄일 수 있다.

검색 결과 AesManaged는 AES HW 가속을 지원하고 AesCryptoServiceProvider 클래스는 AES 가속을 지원하지 않는 것을 확인해 확인하기 위해 간단한 테스트를 하였다.

가정

  • AES의 HW 가속은 순수 SW 연산보다 현저히 빠를 것이다.
  • .NET에서 AesCryptoServiceProvider class는 HW 가속을 지원하며 AesManaged class는 지원하지 않을 것이다.
  • 작은 크기의 많은 AES 연산에서는 overhead로 HW 가속이 더 느릴수 있다.

.NET 4.8, 4KB x 100000 AES encryption

작은 크기에 큰 반복 횟수에서는 AesManaged가 더 빠른 결과를 보였다.

.NET 4.81(ms)2345
AesManaged49684940494749714939
AesCryptoServiceProvider63956407639963236322

.NET 4.8, 1MB x 1000 AES encryption

큰 크기에 낮은 반복 횟수의 암호화는 AES 가속이 되는 AesCryptoServiceProvider 클래스가 월등히 유리하다. 클래스만 변경했을 때 12배 이상 차이가 나는 것을 확인했다.

.NET 4.81(ms)2345
AesCryptoServiceProvider1004983984987984
AesManaged1246812671124361248312436

Code

Linux & OpenSSL

리눅스 에서는 openssl cli로 HW 가속을 테스트할 수 있다.

가능한 경우 EVP_ 접두사 함수들은 기본적으로 AES-NI 를 사용하며 AES_ 접두사 함수들은 사용하지 않는다.

64바이트 이상에서 속도가 3배 이상 차이나는 것을 확인할 수 있다.

$ openssl speed -elapsed -evp aes-128-cbc
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
aes-128-cbc     879157.61k  1346181.01k  1409330.52k  1448567.47k  1479671.81k  1460371.46k

$ OPENSSL_ia32cap="~0x200000200000000" openssl speed -elapsed -evp aes-128-cbc
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
aes-128-cbc     409826.10k   425150.51k   428506.71k   429743.79k   429782.36k   429725.01k

결론

  • .NET 4.8 에서는 AesCryptoServiceProvider 쪽을 사용하는 것이 대개의 경우 더 유리하다.
  • .NET 6.0도 테스트했지만 두 클래스의 속도가 400-600ms로 비슷한 결과가 나왔다. 6.0에서는 AesCryptoServiceProvider 클래스도 HW 가속을 지원하는 것이 아닐까 추측한다.

References