BabaSSL
介紹
BabaSSL是一款輕巧、靈活且靠譜的密碼學和TLS協議工具集。BabaSSL是螞蟻集團和阿里集團的各主要業務中所使用的底層密碼庫,現在開源出來供業界使用。BabaSSL廣泛的應用在包括網絡、存儲、移動端App等場景中。
BabaSSL 是 OpenSSL 的衍生版,內部支持了很多橢圓曲線算法的實現。
github:https://github.com/Tongsuo-Project/Tongsuo
文檔:https://babassl.readthedocs.io/zh/latest/
實現功能:
- 密碼學算法
- 中國商用密碼算法:SM2、SM3、SM4、祖沖之等
- 國際主流算法:ECDSA、RSA、AES、SHA等
- 同態加密算法:EC-ElGamal、Paillier*等
- 後量子密碼學*:LAC、NTRU、Saber、Dilithium等
- 安全通信協議
- 支持GB/T 38636-2020 TLCP標準,即雙證書國密通信協議
- 支持RFC 8998,即TLS 1.3 + 國密單證書
- 支持QUIC API
- 支持Delegated Credentials功能,基於draft-ietf-tls-subcerts-10
- 支持TLS證書壓縮
- 支持緊湊TLS協議*
安裝
參考:https://tongsuo.readthedocs.io/zh/latest/Tutorial/PHE/ec-elgamal-sample/
- 下載
git clone [email protected]:Tongsuo-Project/Tongsuo.git
- 編譯
# 編譯參數需要加上:enable-ec_elgamal,我這裏是在 macOS 系統上編譯,所以是 darwin64-x86_64-cc,其他系統需要切換一下
./Configure darwin64-x86_64-cc --debug no-shared no-threads enable-ec_elgamal --strict-warnings -fPIC --prefix=/usr/local/tongsuo-debug
# 編譯
make -j4
# 安裝到目錄 /usr/local/tongsuo-debug
sudo make install
- Demo(ec_elgamal_test.c)
#include <stdio.h>
#include <time.h>
#include <openssl/ec.h>
#include <openssl/pem.h>
#define CLOCKS_PER_MSEC (CLOCKS_PER_SEC/1000)
int main(int argc, char *argv[])
{
int ret = -1;
uint32_t r;
//密鑰生成
clock_t begin, end;
EC_KEY *sk_eckey = NULL, *pk_eckey = NULL;
EC_ELGAMAL_CTX *ctx1 = NULL, *ctx2 = NULL;
EC_ELGAMAL_CIPHERTEXT *c1 = NULL, *c2 = NULL, *c3 = NULL;
EC_ELGAMAL_DECRYPT_TABLE *table = NULL;
FILE *pk_file = fopen("ec-pk.pem", "rb");
FILE *sk_file = fopen("ec-sk.pem", "rb");
if ((pk_eckey = PEM_read_EC_PUBKEY(pk_file, NULL, NULL, NULL)) == NULL)
goto err;
if ((sk_eckey = PEM_read_ECPrivateKey(sk_file, NULL, NULL, NULL)) == NULL)
goto err;
if ((ctx1 = EC_ELGAMAL_CTX_new(pk_eckey)) == NULL)
goto err;
if ((ctx2 = EC_ELGAMAL_CTX_new(sk_eckey)) == NULL)
goto err;
//創建解密表
begin = clock();
if ((table = EC_ELGAMAL_DECRYPT_TABLE_new(ctx2, 0)) == NULL)
goto err;
EC_ELGAMAL_CTX_set_decrypt_table(ctx2, table);
end = clock();
printf("EC_ELGAMAL_DECRYPT_TABLE_new(1) cost: %lfms\n", (double)(end - begin)/CLOCKS_PER_MSEC);
if ((c1 = EC_ELGAMAL_CIPHERTEXT_new(ctx1)) == NULL)
goto err;
if ((c2 = EC_ELGAMAL_CIPHERTEXT_new(ctx1)) == NULL)
goto err;
//加密20000021
begin = clock();
if (!EC_ELGAMAL_encrypt(ctx1, c1, 20000021))
goto err;
end = clock();
printf("EC_ELGAMAL_encrypt(20000021) cost: %lfms\n", (double)(end - begin)/CLOCKS_PER_MSEC);
//加密500
begin = clock();
if (!EC_ELGAMAL_encrypt(ctx1, c2, 500))
goto err;
end = clock();
printf("EC_ELGAMAL_encrypt(500) cost: %lfms\n", (double)(end - begin)/CLOCKS_PER_MSEC);
if ((c3 = EC_ELGAMAL_CIPHERTEXT_new(ctx1)) == NULL)
goto err;
//密文相加:20000021+500
begin = clock();
if (!EC_ELGAMAL_add(ctx1, c3, c1, c2))
goto err;
end = clock();
printf("EC_ELGAMAL_add(C2000021,C500) cost: %lfms\n", (double)(end - begin)/CLOCKS_PER_MSEC);
//解密:20000021+500
begin = clock();
if (!(EC_ELGAMAL_decrypt(ctx2, &r, c3)))
goto err;
end = clock();
printf("EC_ELGAMAL_decrypt(C20000021,C500) result: %d, cost: %lfms\n", r, (double)(end - begin)/CLOCKS_PER_MSEC);
//標量乘:500*800
begin = clock();
if (!EC_ELGAMAL_mul(ctx1, c3, c2, 800))
goto err;
end = clock();
printf("EC_ELGAMAL_mul(C500,800) cost: %lfms\n", (double)(end - begin)/CLOCKS_PER_MSEC);
//解密:500*800
begin = clock();
if (!(EC_ELGAMAL_decrypt(ctx2, &r, c3)))
goto err;
end = clock();
printf("EC_ELGAMAL_decrypt(C500,800) result: %d, cost: %lfms\n", r, (double)(end - begin)/CLOCKS_PER_MSEC);
//將密文500*800編碼爲二進制文件
printf("EC_ELGAMAL_CIPHERTEXT_encode size: %zu\n", EC_ELGAMAL_CIPHERTEXT_encode(ctx2, NULL, 0, NULL, 1));
ret = 0;
err:
EC_KEY_free(sk_eckey);
EC_KEY_free(pk_eckey);
EC_ELGAMAL_DECRYPT_TABLE_free(table);
EC_ELGAMAL_CIPHERTEXT_free(c1);
EC_ELGAMAL_CIPHERTEXT_free(c2);
EC_ELGAMAL_CIPHERTEXT_free(c3);
EC_ELGAMAL_CTX_free(ctx1);
EC_ELGAMAL_CTX_free(ctx2);
fclose(sk_file);
fclose(pk_file);
return ret;
}
- 編譯demo
gcc -Wall -g -o ec_elgamal_test ./ec_elgamal_test.c -I/usr/local/tongsuo-debug/include -L/usr/local/tongsuo-debug/lib -lssl -lcrypto
- 生成公私鑰
# 先生成私鑰,這裏生成的是 SM2 曲線的私鑰
/usr/local/tongsuo-debug/bin/openssl ecparam -genkey -name SM2 -out ec-sk.pem
# 用私鑰生成公鑰
/usr/local/tongsuo-debug/bin/openssl ec -in ./ec-sk.pem -pubout -out ec-pk.pem
- 運行
./ec_elgamal_test
EC_ELGAMAL_DECRYPT_TABLE_new(1) cost: 2410.917000ms
EC_ELGAMAL_encrypt(20000021) cost: 1.605000ms
EC_ELGAMAL_encrypt(500) cost: 1.547000ms
EC_ELGAMAL_add(C2000021,C500) cost: 0.019000ms
EC_ELGAMAL_decrypt(C20000021,C500) result: 20000521, cost: 12.281000ms
EC_ELGAMAL_mul(C500,800) cost: 2.257000ms
EC_ELGAMAL_decrypt(C500,800) result: 400000, cost: 1.216000ms
EC_ELGAMAL_CIPHERTEXT_encode size: 66
- 注意
EC_ELGAMAL_DECRYPT_TABLE_new
函數第二個參數(0不支持,1支持)指定是否支持負數解密(爲 1 時表示該解密表可以解密負數,初始化解密表時將可能的負數運算後插入到 hash 中),如果支持負數解密會影響解密性能,因爲查詢解密表的次數變多了,以及點的運算變多了,同時構造支持負數的解密表需要的時間也比較長。如下是支持負數解密的運行結果:
EC_ELGAMAL_DECRYPT_TABLE_new(1) cost: 114581.404000ms
EC_ELGAMAL_encrypt(20000021) cost: 1.806000ms
EC_ELGAMAL_encrypt(500) cost: 1.783000ms
EC_ELGAMAL_add(C2000021,C500) cost: 0.011000ms
EC_ELGAMAL_decrypt(C20000021,C500) result: 20000521, cost: 532.148000ms
EC_ELGAMAL_mul(C500,800) cost: 1.759000ms
EC_ELGAMAL_decrypt(C500,800) result: 400000, cost: 292.958000ms
EC_ELGAMAL_CIPHERTEXT_encode size: 66