C/C++

C 語言使用 OpenSSL 實作 PBKDF2 教學與範例

介紹如何在 C 語言中使用 OpenSSL 函式庫實作各種 PBKDF2 密鑰延伸演算法。

PBKDF2(Password-Based Key Derivation Function)是一種密鑰延伸(key stretching)演算法,透過反覆的大量運算,降低密鑰產生的速度,讓暴力破解的難度變高。實務上 PBKDF2 會搭配 SHA1、SHA256、SHA512 等雜湊演算法,以下是以 OpenSSL 函式庫實作的 C 語言範例。

PBKDF2-HMAC-SHA1

OpenSSL 的 PKCS5_PBKDF2_HMAC_SHA1() 可以用來計算 PBKDF2-HMAC-SHA1,以下是使用範例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>

int main() {
	const char password[] = "password";       // 文字密碼
	unsigned char salt[] = {'s','a','l','t'}; // Salt
	const int KEY_LEN = 20;                   // 輸出密鑰長度
	unsigned char key[KEY_LEN];               // 輸出的密鑰
	int iter = 2;                             // 迭代次數

	// 以 OpenSSL 計算 PBKDF2-HMAC-SHA1
	PKCS5_PBKDF2_HMAC_SHA1(
			password,           // 文字密碼(輸入)
			strlen(password),   // 文字密碼長度(輸入)
			salt,               // Salt(輸入)
			sizeof(salt),       // Salt 長度(輸入)
			iter,               // 迭代次數
			KEY_LEN,            // 密鑰長度(輸出)
			key);               // 密鑰(輸出)

	// 輸出 PBKDF2-HMAC-SHA1 計算結果
	BIO_dump_fp(stdout, key, KEY_LEN);

	return EXIT_SUCCESS;
}

將其儲存為 pbkdf2_hmac_sha1.c 之後,使用以下指令進行編譯:

# 編譯 OpenSSL 程式
gcc -o pbkdf2_hmac_sha1 pbkdf2_hmac_sha1.c -lcrypto

# 執行程式
./pbkdf2_hmac_sha1
0000 - ea 6c 01 4d c7 2d 6f 8c-cd 1e d9 2a ce 1d 41 f0   .l.M.-o....*..A.
0010 - d8 de 89 57                                       ...W

我們可以參考 RFC6070,跟文件中的範例對照,確認自己程式的正確性,以下是 RFC6070 中對應的範例:

Input:
  P = "password" (8 octets)
  S = "salt" (4 octets)
  c = 2
  dkLen = 20

Output:
  DK = ea 6c 01 4d c7 2d 6f 8c
       cd 1e d9 2a ce 1d 41 f0
       d8 de 89 57             (20 octets)

PBKDF2-HMAC-SHA256

若要採用 SHA1 以外的雜揍演算法,可以使用 OpenSSL 的 PKCS5_PBKDF2_HMAC() 函數,並自行指定要採用的雜湊方式,以下是採用 SHA-256 的範例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>

int main() {
	const char password[] = "password";       // 文字密碼
	unsigned char salt[] = {'s','a','l','t'}; // Salt
	const int KEY_LEN = 20;                   // 輸出密鑰長度
	unsigned char key[KEY_LEN];               // 輸出的密鑰
	int iter = 2;                             // 迭代次數

	// 以 OpenSSL 計算 PBKDF2-HMAC-SHA256
	PKCS5_PBKDF2_HMAC(
			password,           // 文字密碼(輸入)
			strlen(password),   // 文字密碼長度(輸入)
			salt,               // Salt(輸入)
			sizeof(salt),       // Salt 長度(輸入)
			iter,               // 迭代次數
			EVP_sha256(),       // 採用 SHA-256 雜湊
			KEY_LEN,            // 密鑰長度(輸出)
			key);               // 密鑰(輸出)

	// 輸出 PBKDF2-HMAC-SHA256 計算結果
	BIO_dump_fp(stdout, key, KEY_LEN);

	return EXIT_SUCCESS;
}

將其儲存為 pbkdf2_hmac_sha256.c 之後,使用以下指令進行編譯:

# 編譯 OpenSSL 程式
gcc -o pbkdf2_hmac_sha256 pbkdf2_hmac_sha256.c -lcrypto

# 執行程式
./pbkdf2_hmac_sha256
0000 - ae 4d 0c 95 af 6b 46 d3-2d 0a df f9 28 f0 6d d0   .M...kF.-...(.m.
0010 - 2a 30 3f 8e                                       *0?.

PKCS5_PBKDF2_HMAC() 函數呼叫時,可以自由搭配各種雜湊演算法,常見的雜湊方式有 EVP_md5()EVP_sha1()EVP_sha224()EVP_sha256()EVP_sha384()EVP_sha512() 等。

以 Python 驗證

我們也可以使用 Python 的程式來驗證 PBKDF2 的計算結果,以下是使用 PyCryptodome 模組來計算 PBKDF2 的程式:

from Crypto.Protocol.KDF import PBKDF2
from Crypto.Hash import SHA1, SHA256

# 文字密碼與 Salt
password = b'password'
salt = b'salt'

# 計算 PBKDF2-HMAC-SHA1
key1 = PBKDF2(password, salt, 20, count=2, hmac_hash_module=SHA1)
print("PBKDF2-HMAC-SHA1: {}".format(key1.hex()))
PBKDF2-HMAC-SHA1: ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957
# 計算 PBKDF2-HMAC-SHA256
key256 = PBKDF2(password, salt, 20, count=2, hmac_hash_module=SHA256)
print("PBKDF2-HMAC-SHA256: {}".format(key256.hex()))
PBKDF2-HMAC-SHA256: ae4d0c95af6b46d32d0adff928f06dd02a303f8e

另外 Python 的 Cryptography 模組也可以用來驗證 PBKDF2 的計算結果,使用方式大同小異。

參考資料

Share
Published by
Office Guide

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

1 年 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

1 年 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

1 年 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

1 年 ago