c语言开发 php扩展 sm4

首先 php可以直接调用openssl 直接进行sm4 sm3的加密

如:
openssl_encrypt($plaintext, 'sm4-cbc', $key, OPENSSL_RAW_DATA , $iv);
openssl_digest('123','sm3')

php如果直接调用sm2 需要统一使用openssl的evp接口
openssl1.1的源码在sm2_crypt文件里面

此处只是学习

/* gmtest extension for PHP */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "php.h"
#include "ext/standard/info.h"
#include "php_gmtest.h"
#include "zend_exceptions.h"

//这里使用openssl 1.1版本 include 为加载库 lib 为链接库
#include <openssl/evp.h>
#include "ext/standard/base64.h"

/* For compatibility with older PHP versions */
#ifndef ZEND_PARSE_PARAMETERS_NONE
#define ZEND_PARSE_PARAMETERS_NONE() \
	ZEND_PARSE_PARAMETERS_START(0, 0) \
	ZEND_PARSE_PARAMETERS_END()
#endif

/* {{{ void gmtest_test1()
 */
PHP_FUNCTION(gmtest_test1)
{
	ZEND_PARSE_PARAMETERS_NONE();

	php_printf("The extension %s is loaded and working!\r\n", "gmtest");
}
/* }}} */

/* {{{ string gmtest_test2( [ string $var ] )
 */
PHP_FUNCTION(gmtest_test2)
{
	char *var = "World";
	size_t var_len = sizeof("World") - 1;
	zend_string *retval;

	ZEND_PARSE_PARAMETERS_START(0, 1)
		Z_PARAM_OPTIONAL
		Z_PARAM_STRING(var, var_len)
	ZEND_PARSE_PARAMETERS_END();

	retval = strpprintf(0, "Hello %s", var);

	RETURN_STR(retval);
}
/* }}}*/


/* {{{ sm4解密 类似为aes string gmtest_caotl_sm4_jiami( [ string $var ] )
 */
PHP_FUNCTION(gmtest_caotl_sm4_jiami)
{
	

	 zend_string *plaintext;
    zend_string *key = NULL;
    zend_string *iv = NULL;
    unsigned char *ciphertext;
    int key_len, iv_len, plaintext_len, ciphertext_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|SS", &plaintext, &key, &iv) == FAILURE) {
        return;
    }


   	key_len = key ? ZSTR_LEN(key) : 16;
    iv_len = iv ? ZSTR_LEN(iv) : 16;
    plaintext_len = ZSTR_LEN(plaintext);
    ciphertext_len = plaintext_len + EVP_MAX_BLOCK_LENGTH; // 最大可能的密文长度

	ciphertext = emalloc(ciphertext_len);

    int len;

	EVP_CIPHER_CTX *cipher_ctx;
	
	
	cipher_ctx = EVP_CIPHER_CTX_new();

	if (!cipher_ctx) {
		php_error_docref(NULL, E_WARNING, "Failed to create cipher context");
		RETVAL_FALSE;
	}

	EVP_EncryptInit_ex(cipher_ctx, EVP_sm4_ecb(), NULL, (unsigned char *)ZSTR_VAL(key), (unsigned char *)ZSTR_VAL(iv));

	EVP_EncryptUpdate(cipher_ctx, ciphertext, &len, (unsigned char *)ZSTR_VAL(plaintext), plaintext_len);

	 // 结束加密过程
    EVP_EncryptFinal_ex(cipher_ctx, ciphertext + len, &len);
    
	EVP_CIPHER_CTX_free(cipher_ctx);

	zend_string *str = zend_string_init((const char *)ciphertext, len, 0);

	RETVAL_STR(str);
}
/* }}}*/

/* {{{ sm4解密 类似为aes string gmtest_caotl_sm4_jiami( [ string $var ] )
 */
PHP_FUNCTION(gmtest_caotl_sm4_jiemi)
{
	

	 zend_string *plaintext;
    zend_string *key = NULL;
    zend_string *iv = NULL;
    unsigned char *ciphertext;
    int key_len, iv_len, plaintext_len, ciphertext_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|SS", &plaintext, &key, &iv) == FAILURE) {
        return;
    }


   	key_len = key ? ZSTR_LEN(key) : 16;
    iv_len = iv ? ZSTR_LEN(iv) : 16;
    plaintext_len = ZSTR_LEN(plaintext);
    ciphertext_len = plaintext_len + EVP_MAX_BLOCK_LENGTH; // 最大可能的密文长度

	ciphertext = emalloc(ciphertext_len);

    int len;

	EVP_CIPHER_CTX *cipher_ctx;
	
	
	cipher_ctx = EVP_CIPHER_CTX_new();

	if (!cipher_ctx) {
		php_error_docref(NULL, E_WARNING, "Failed to create cipher context");
		RETVAL_FALSE;
	}

	EVP_DecryptInit_ex(cipher_ctx, EVP_sm4_ecb(), NULL, (unsigned char *)ZSTR_VAL(key), (unsigned char *)ZSTR_VAL(iv));

	EVP_DecryptUpdate(cipher_ctx, ciphertext, &len, (unsigned char *)ZSTR_VAL(plaintext), plaintext_len);

	 // 结束加密过程
    EVP_DecryptFinal_ex(cipher_ctx, ciphertext + len, &len);
    
	EVP_CIPHER_CTX_free(cipher_ctx);

	zend_string *str = zend_string_init((const char *)ciphertext, len, 0);

	RETVAL_STR(str);
}
/* }}}*/



/* {{{ PHP_RINIT_FUNCTION
 */
PHP_RINIT_FUNCTION(gmtest)
{
#if defined(ZTS) && defined(COMPILE_DL_GMTEST)
	ZEND_TSRMLS_CACHE_UPDATE();
#endif

	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MINFO_FUNCTION
 */
PHP_MINFO_FUNCTION(gmtest)
{
	php_info_print_table_start();
	php_info_print_table_header(2, "gmtest support", "enabled");
	php_info_print_table_end();
}
/* }}} */

/* {{{ arginfo
 */
ZEND_BEGIN_ARG_INFO(arginfo_gmtest_test1, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO(arginfo_gmtest_test2, 0)
	ZEND_ARG_INFO(0, str)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_gmtest_caotl_sm4_jiami, 0, 0, 1)
    ZEND_ARG_INFO(0, plaintext)
    ZEND_ARG_INFO(0, key)
    ZEND_ARG_INFO(0, iv)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_gmtest_caotl_sm4_jiemi, 0, 0, 1)
    ZEND_ARG_INFO(0, plaintext)
    ZEND_ARG_INFO(0, key)
    ZEND_ARG_INFO(0, iv)
ZEND_END_ARG_INFO()
/* }}} */

/* {{{ gmtest_functions[]
 */
static const zend_function_entry gmtest_functions[] = {
	PHP_FE(gmtest_test1,		arginfo_gmtest_test1)
	PHP_FE(gmtest_test2,		arginfo_gmtest_test2)
	PHP_FE(gmtest_caotl_sm4_jiami,		arginfo_gmtest_caotl_sm4_jiami)
	PHP_FE(gmtest_caotl_sm4_jiemi,		arginfo_gmtest_caotl_sm4_jiemi)
	PHP_FE_END
};
/* }}} */

/* {{{ gmtest_module_entry
 */
zend_module_entry gmtest_module_entry = {
	STANDARD_MODULE_HEADER,
	"gmtest",					/* Extension name */
	gmtest_functions,			/* zend_function_entry */
	NULL,							/* PHP_MINIT - Module initialization */
	NULL,							/* PHP_MSHUTDOWN - Module shutdown */
	PHP_RINIT(gmtest),			/* PHP_RINIT - Request initialization */
	NULL,							/* PHP_RSHUTDOWN - Request shutdown */
	PHP_MINFO(gmtest),			/* PHP_MINFO - Module info */
	PHP_GMTEST_VERSION,		/* Version */
	STANDARD_MODULE_PROPERTIES
};
/* }}} */

#ifdef COMPILE_DL_GMTEST
# ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
# endif
ZEND_GET_MODULE(gmtest)
#endif


posted @ 2024-06-12 17:20  尘梦  阅读(3)  评论(0编辑  收藏  举报