OpenSSL项目最近6个月添加了许多新特性, 包括对中国SM2/SM3/SM4算法的支持:
- SM2椭圆曲线: https:///openssl/openssl/pull/4793
- SM3哈希摘要: https:///openssl/openssl/pull/4616
- SM4对称加密: https:///openssl/openssl/pull/4552
参考: 中国国家密码管理局制定的商业密码算法标准
- 《GM/T 0006-2012 密码应用标识规范》定义国密算法OID标识
- 《GB/T 32907-2016 SM4分组密码算法》(原GM/T 0002-2012)
- 《GB/T 329??-2016 SM2椭圆曲线公钥密码算法》(原GM/T 0003-2012)
- 《GB/T 32905-2016 SM3密码杂凑算法》(原GM/T 0004-2012)
下载源码
- https://www.openssl.org/source/openssl-1.1.1-pre4.tar.gz
- https://www.openssl.org/source/openssl-1.1.1-pre5.tar.gz
解压缩
-
tar xzvf openssl-1.1.1-pre4.tar.gz -
tar xzvf openssl-1.1.1-pre5.tar.gz
编译步骤
-
cd openssl-1.1.1-pre5 -
./config -
make
本地安装(可选步骤)
sudo make install
配置LD_LIBRARY_PATH并检查openssl可执行程序版本号
-
$ export LD_LIBRARY_PATH=`pwd` -
-
$ ./apps/openssl version -
OpenSSL 1.1.1-pre5 (beta) 17 Apr 2018
检查 SM3 哈希校验和
-
$ echo -n "abc" | ./apps/openssl dgst -SM3 -
(stdin)= 66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0
检查椭圆曲线是否包含SM2
-
$ ./apps/openssl ecparam -list_curves | grep SM2 -
SM2 : SM2 curve over a 256 bit prime field
检查对称算法
-
./apps/openssl enc -ciphers -
-sm4 -
-sm4-cbc -
-sm4-cfb -
-sm4-ctr -
-sm4-ecb -
-sm4-ofb
???
SM4-自测试数据- 测试SM4-ECB电子密码本模式, 选取AES-128-ECB作为参考
https:///liuqun/openssl-sm4-demo/ -
/** 文件名: https:///liuqun/openssl-sm4-demo/blob/cmake/src/main.c */ -
#include <stddef.h> -
#include <stdio.h> -
#include <stdlib.h> -
#include <string.h> -
#include "openssl/err.h" -
#include "openssl/evp.h" -
-
/* Before OpenSSL 1.1.1-pre1, we did not have EVP_sm4_ecb() */ -
#if defined(OPENSSL_VERSION_NUMBER) \ -
&& OPENSSL_VERSION_NUMBER < 0x10101001L -
static const EVP_CIPHER *(*EVP_sm4_ecb)()=EVP_aes_128_ecb; -
#endif -
-
typedef struct { -
const unsigned char *in_data; -
size_t in_data_len; -
int in_data_is_already_padded; -
const unsigned char *in_ivec; -
const unsigned char *in_key; -
size_t in_key_len; -
} test_case_t; -
-
-
void test_encrypt_with_cipher(const test_case_t *in, const EVP_CIPHER *cipher) -
{ -
unsigned char *out_buf = NULL; -
int out_len; -
int out_padding_len; -
EVP_CIPHER_CTX *ctx; -
-
ctx = EVP_CIPHER_CTX_new(); -
EVP_EncryptInit_ex(ctx, cipher, NULL, in->in_key, in->in_ivec); -
-
if (in->in_data_is_already_padded) -
{ -
/* Check whether the input data is already padded. -
And its length must be an integral multiple of the cipher's block size. */ -
const size_t bs = EVP_CIPHER_block_size(cipher); -
if (in->in_data_len % bs != 0) -
{ -
printf("ERROR-1: data length=%d which is not added yet; block size=%d\n", (int) in->in_data_len, (int) bs); -
/* Warning: Remember to do some clean-ups */ -
EVP_CIPHER_CTX_free(ctx); -
return; -
} -
/* Disable the implicit PKCS#7 padding defined in EVP_CIPHER */ -
EVP_CIPHER_CTX_set_padding(ctx, 0); -
} -
-
out_buf = (unsigned char *) malloc(((in->in_data_len>>4)+1) << 4); -
out_len = 0; -
EVP_EncryptUpdate(ctx, out_buf, &out_len, in->in_data, in->in_data_len); -
if (1) -
{ -
printf("Debug: out_len=%d\n", out_len); -
} -
-
out_padding_len = 0; -
EVP_EncryptFinal_ex(ctx, out_buf+out_len, &out_padding_len); -
if (1) -
{ -
printf("Debug: out_padding_len=%d\n", out_padding_len); -
} -
-
EVP_CIPHER_CTX_free(ctx); -
if (1) -
{ -
int i; -
int len; -
len = out_len + out_padding_len; -
for (i=0; i<len; i++) -
{ -
printf("%02x ", out_buf[i]); -
} -
printf("\n"); -
} -
-
if (out_buf) -
{ -
free(out_buf); -
out_buf = NULL; -
} -
} -
-
void main() -
{ -
int have_sm4 = (OPENSSL_VERSION_NUMBER >= 0x10101001L); -
int have_aes = 1; -
const unsigned char data[]= -
{ -
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, -
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, -
}; -
unsigned char ivec[EVP_MAX_IV_LENGTH]; ///< IV 向量 -
const unsigned char key1[16] = ///< key_data, 密钥内容, 至少16字节 -
{ -
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, -
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, -
}; -
test_case_t tc; -
-
tc.in_data = data; -
tc.in_data_len = sizeof(data); -
tc.in_data_is_already_padded = (tc.in_data_len % 16)==0; // Hard coded 16 as the cipher's block size -
tc.in_key = key1; -
tc.in_key_len = sizeof(key1); -
memset(ivec, 0x00, EVP_MAX_IV_LENGTH); -
tc.in_ivec = ivec; -
-
#if defined(OPENSSL_NO_SM4) -
have_sm4 = 0; -
#endif -
if (have_sm4) -
{ -
printf("[1]\n"); -
printf("Debug: EVP_sm4_ecb() test\n"); -
test_encrypt_with_cipher(&tc, EVP_sm4_ecb()); -
} -
#if defined(OPENSSL_NO_AES) -
have_aes = 0; -
#endif -
if (have_aes) -
{ -
printf("[2]\n"); -
printf("Debug: EVP_aes_128_ecb() test\n"); -
test_encrypt_with_cipher(&tc, EVP_aes_128_ecb()); -
} -
} -
假定当前是把main.c放在 openssl-1.1.1-pre5/文件夹内 -
gcc -Iinclude -c main.c -
gcc main.o libcrypto.so -o a.out -
-
export LD_LIBRARY_PATH=`pwd` -
ldd a.out -
-
./a.out
9.1. GM/T OIDs
9.1.1. SCA OID Prefix
All SM4 GM/T OIDs belong under the "1.2.156.10197" OID prefix,
registered by the Chinese Cryptography Standardization Technology
Committee ("CCSTC"), a committee under the SCA. Its components are
described below in ASN.1 notation.