调用 openssl的接口的 (openssl版本有很多版本,我是调用 1.1.1a 版本,有两个dll文件 libcrypt-1_1.dll libssl-1_1.dll)
我有写了个包
DECLARE integer MD5 IN libcrypto-1_1.dll AS api_md5 STRING,INTEGER,STRING @
*!* DECLARE integer SHA IN libcrypto-1_1.dll AS api_sha STRING,INTEGER,STRING @
DECLARE integer SHA1 IN libcrypto-1_1.dll AS api_sha1 STRING,INTEGER,STRING @
DECLARE integer SHA256 IN libcrypto-1_1.dll AS api_sha256 STRING,INTEGER,STRING @
DECLARE integer SHA512 IN libcrypto-1_1.dll AS api_sha512 STRING,INTEGER,STRING @
DECLARE INTEGER BIO_new_mem_buf IN libcrypto-1_1.dll AS api_BIO_new_mem_buf STRING,INTEGER
DECLARE INTEGER BIO_free_all IN libcrypto-1_1.dll AS api_BIO_free_all INTEGER
DECLARE INTEGER PEM_read_bio_RSA_PUBKEY IN libcrypto-1_1.dll AS api_PEM_read_bio_RSA_PUBKEY INTEGER,INTEGER, INTEGER,INTEGER
DECLARE INTEGER PEM_read_bio_RSAPrivateKey IN libcrypto-1_1.dll AS api_PEM_read_bio_RSAPrivateKey INTEGER,INTEGER, INTEGER,INTEGER
DECLARE INTEGER RSA_free IN libcrypto-1_1.dll AS api_RSA_free INTEGER
DECLARE integer RSA_sign IN libcrypto-1_1.dll AS api_RSA_sign INTEGER,STRING,INTEGER,STRING @,INTEGER @, INTEGER
DECLARE integer RSA_verify IN libcrypto-1_1.dll AS api_RSA_verify INTEGER,STRING,INTEGER,STRING,INTEGER, INTEGER
DECLARE INTEGER EVP_md5 IN libcrypto-1_1.dll AS api_EVP_md5
DECLARE INTEGER EVP_sha1 IN libcrypto-1_1.dll AS api_EVP_sha1
DECLARE INTEGER EVP_sha256 IN libcrypto-1_1.dll AS api_EVP_sha256
DECLARE INTEGER EVP_sha512 IN libcrypto-1_1.dll AS api_EVP_sha512
DECLARE INTEGER HMAC IN libcrypto-1_1.dll AS api_HMAC INTEGER, STRING, INTEGER, STRING, INTEGER, STRING @,INTEGER @
** unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, const unsigned char *d, size_t n, unsigned char *md, unsigned int *md_len);
DECLARE INTEGER AES_set_encrypt_key IN libcrypto-1_1.dll AS api_AES_set_encrypt_key STRING, INTEGER, STRING @
** int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key)
DECLARE INTEGER AES_set_decrypt_key IN libcrypto-1_1.dll AS api_AES_set_decrypt_key STRING, INTEGER, STRING @
** int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key)
DECLARE AES_cbc_encrypt IN libcrypto-1_1.dll AS api_AES_cbc_encrypt STRING, STRING @, INTEGER, STRING, STRING, INTEGER
** void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, const int enc)
function openssl_sign
PARAMETERS m_type, m_plain, m_prikey
#define NID_sha1 64
#define NID_md5 4
#define NID_sha256 672
#define NID_sha512 674
LOCAL m_hash, m_len ,m_nid_type,m_s
LOCAL m_bio,m_rsa
DO case
CASE m_type='MD5'
m_nid_type = NID_md5
m_len = 16
m_hash=SPACE(m_len)
api_md5(m_plain,LEN(m_plain),@m_hash)
CASE m_type='SHA1'
m_nid_type = NID_sha1
m_len = 20
m_hash=SPACE(m_len)
api_sha1(m_plain,LEN(m_plain),@m_hash)
CASE m_type='SHA256'
m_nid_type = NID_sha256
m_len = 32
m_hash=SPACE(m_len)
api_sha256(m_plain,LEN(m_plain),@m_hash)
CASE m_type='SHA512'
m_nid_type = NID_sha512
m_len = 64
m_hash=SPACE(m_len)
api_sha512(m_plain,LEN(m_plain),@m_hash)
OTHERWISE
RETURN '1非法的hash类型'
ENDCASE
IF EMPTY(m_hash)
RETURN '1hash结果为空'
ENDIF
IF EMPTY(m_prikey)
RETURN '1key为空'
ENDIF
IF LEFT(m_prikey,5)<>'-----'
m_s='-----BEGIN RSA PRIVATE KEY-----'+CHR(10)
DO WHILE .T.
M_S = M_S+RTRIM(SUBSTR(m_prikey,1,64))+CHR(10)
M_PRIKEY = SUBSTR(M_PRIKEY,65)
IF EMPTY(M_PRIKEY)
EXIT
ENDIF
ENDDO
m_s=m_s+'-----END RSA PRIVATE KEY-----'+CHR(10)
m_prikey = m_s
ENDIF
m_bio = api_BIO_new_mem_buf(m_prikey,LEN(m_prikey))
IF m_bio<=0
RETURN '1无法生成bio'
ENDIF
m_rsa = api_PEM_read_bio_RSAPrivateKey(m_bio,0,0, 0)
IF m_rsa<=0
api_BIO_free_all(m_bio)
RETURN '1无法生成rsa'
ENDIF
LOCAL m_result, m_sign, m_signlen
m_sign=SPACE(4096)
m_signlen = 0
m_result = api_RSA_sign(m_nid_type,m_hash,m_len,@m_sign, @m_signlen,m_rsa)
api_RSA_free(m_rsa)
api_BIO_free_all(m_bio)
IF m_result<>1
RETURN '1无法生成签名'
ENDIF
IF m_signlen =0
RETURN '1无法生成签名,长度为零'
ENDIF
m_sign = LEFT(m_sign,m_signlen)
RETURN '0'+STRCONV(m_sign,13)
function openssl_verify
PARAMETERS m_type, m_plain, m_pubkey,m_sign
#define NID_sha1 64
#define NID_md5 4
#define NID_sha256 672
#define NID_sha512 674
LOCAL m_hash, m_len ,m_nid_type,m_s
LOCAL m_bio,m_rsa
DO case
CASE m_type='MD5'
m_nid_type = NID_md5
m_len = 16
m_hash=SPACE(m_len)
api_md5(m_plain,LEN(m_plain),@m_hash)
CASE m_type='SHA1'
m_nid_type = NID_sha1
m_len = 20
m_hash=SPACE(m_len)
api_sha1(m_plain,LEN(m_plain),@m_hash)
CASE m_type='SHA256'
m_nid_type = NID_sha256
m_len = 32
m_hash=SPACE(m_len)
api_sha256(m_plain,LEN(m_plain),@m_hash)
CASE m_type='SHA512'
m_nid_type = NID_sha512
m_len = 64
m_hash=SPACE(m_len)
api_sha512(m_plain,LEN(m_plain),@m_hash)
OTHERWISE
RETURN '1非法的hash类型'
ENDCASE
IF EMPTY(m_hash)
RETURN '1hash结果为空'
ENDIF
IF EMPTY(m_pubkey)
RETURN '1key为空'
ENDIF
IF LEFT(m_pubkey,5)<>'-----'
m_s='-----BEGIN PUBLIC KEY-----'+CHR(10)
DO WHILE .T.
M_S = M_S+RTRIM(SUBSTR(m_pubkey,1,64))+CHR(10)
M_pubkey = SUBSTR(M_pubkey,65)
IF EMPTY(M_pubkey)
EXIT
ENDIF
ENDDO
m_s=m_s+'-----END PUBLIC KEY-----'+CHR(10)
m_pubkey = m_s
ENDIF
m_bio = api_BIO_new_mem_buf(m_pubkey,LEN(m_pubkey))
IF m_bio<=0
RETURN '1无法生成bio'
ENDIF
m_rsa = api_PEM_read_bio_RSA_PUBKEY(m_bio,0,0, 0)
IF m_rsa<=0
api_BIO_free_all(m_bio)
RETURN '1无法生成rsa'
ENDIF
LOCAL m_result, m_signlen
m_sign= STRCONV(m_sign,14)
m_signlen = m_len * 8 &&
m_result = api_RSA_verify(m_nid_type,m_hash,m_len,m_sign, m_signlen,m_rsa)
api_RSA_free(m_rsa)
api_BIO_free_all(m_bio)
IF m_RESULT=1
RETURN '0VERIFY OK'
ELSE
RETURN '1VERIFY FAILURE'
ENDIF
去网上看openssl api文档,里面调用范例很容易改成VFP的
下载地址:
https://download.csdn.net/download/trainee/14937854?spm=1001.2014.3001.5501
https://download.csdn.net/download/trainee/14937962?spm=1001.2014.3001.5501