实验一-密码引擎-加密API实现与测试
- 实现 GM/T 0018-2012 密码设备应用接口规范中部分接口函数。
- 以 SDF_ExternalEncrypt_ECC、 SDF_HashUpdate 等为例。
// sdf.h
int SDF_ExternalEncrypt_ECC(
void* hSessionHandle,
unsigned int uiAlgID,
ECCrefPublicKey* pucPublicKey,
unsigned char* pucData,
unsigned int uiDataLength,
ECCCipher* pucEncData
);
int SDF_ExternalDecrypt_ECC(
void* hSessionHandle,
unsigned int uiAlgID,
ECCrefPrivateKey* pucPrivateKey,
ECCCipher* pucEncData,
unsigned char* pucData,
unsigned int* puiDataLength
);
int SDF_HashInit(void* hSessionHandle,
unsigned int uiAlgID,
ECCrefPublicKey* pucPublicKey,
unsigned char* pucID,
unsigned int uiIDLength);
int SDF_HashUpdate(void* hSessionHandle,
unsigned char* pucData,
unsigned int uiDataLength);
int SDF_HashFinal(void* hSessionHandle,
unsigned char* pucHash,
unsigned int* puiHashLength);
调用 OpenSSL 接口来封装上述函数。
// sdf.c
int SDF_ExternalEncrypt_ECC(void* hSessionHandle, unsigned int uiAlgID, ECCrefPublicKey* pucPublicKey, unsigned char* pucData, unsigned int uiDataLength, ECCCipher* pucEncData)
{
if (uiDataLength > 32) {
printf("Too much bytes for pucData!\n");
return SDR_PKOPERR;
}
int error_code;
unsigned char c1[65], c3[32];
unsigned char* c2;
int i;
unsigned char pub_key[65] = { 0x04 };
for (i = 1; i < 33; i++) {
pub_key[i] = pucPublicKey->x[i-1];
}
for (i = 33; i < 65; i++) {
pub_key[i] = pucPublicKey->y[i-33];
}
if (!(c2 = (unsigned char*)malloc(uiDataLength)))
{
printf("Memory allocation failed!\n");
return SDR_NOBUFFER;
}
if (error_code = sm2_encrypt(pucData, uiDataLength, pub_key, c1, c3, c2)) {
printf("Create SM2 ciphertext by using input defined in standard failed!\n");
free(c2);
return SDR_PKOPERR;
}
for (i = 0; i < 32; i++) {
pucEncData->x[i] = c1[i+1];
}
for (i = 0; i < 32; i++) {
pucEncData->y[i] = c1[i+33];
}
for (i = 0; i < uiDataLength; i++) {
pucEncData->C[i] = c2[i];
}
for (i = uiDataLength; i < 32; i++) {
pucEncData->C[i] = 0x00;
}
for (i = 0; i < 32; i++) {
pucEncData->M[i] = c3[i];
}
return SDR_OK;
}
- 其中函数 sm2_encrypt 是参考了 Github 上的项目,可以从此连接进行查看。 https://github.com/greendow/SM2-encrypt-and-decrypt
- 解密后的结果与原先一致:
// sdf.h
int SDF_HashInit(void* hSessionHandle,
unsigned int uiAlgID,
ECCrefPublicKey* pucPublicKey,
unsigned char* pucID,
unsigned int uiIDLength);
int SDF_HashUpdate(void* hSessionHandle,
unsigned char* pucData,
unsigned int uiDataLength);
int SDF_HashFinal(void* hSessionHandle,
unsigned char* pucHash,
unsigned int* puiHashLength);
// sdf.c
int SDF_HashInit(void* hSessionHandle, unsigned int uiAlgID,
ECCrefPublicKey* pucPublicKey, unsigned char* pucID, unsigned int uiIDLength) {
EVP_MD_CTX* md_ctx = EVP_MD_CTX_new();
const EVP_MD* md = EVP_sm3();
EVP_DigestInit_ex(md_ctx, md, NULL);
return SDR_OK;
}
int SDF_HashUpdate(void* hSessionHandle, unsigned char* pucData, unsigned int uiDataLength) {
EVP_DigestUpdate(md_ctx, pucData, uiDataLength);
return SDR_OK;
}
int SDF_HashFinal(void* hSessionHandle, unsigned char* pucHash, unsigned int* puiHashLength) {
EVP_DigestFinal_ex(md_ctx, pucHash, puiHashLength);
EVP_MD_CTX_free(md_ctx);
return SDR_OK;
}
- SDF 规范中与哈希运算相关的函数都可以直接调用 OpenSSL 中的接口,稍作修改即可完成。
- 计算字符串“20191210”的散列值,与 OpenSSL 的计算结果一致。
星光荡开宇宙