php pkcs7签名验签算法,OpenSSL 签名验签接口调用及测试
OpenSSL 簽名驗(yàn)簽接口調(diào)用及測試
概述
項(xiàng)目中我們經(jīng)常會遇到開發(fā)簽名、驗(yàn)簽功能。簽名、驗(yàn)簽是可信賴網(wǎng)絡(luò)的一個(gè)重要功能。因此,我記錄了OpenSSL 簽名驗(yàn)簽接口調(diào)用及測試。
相關(guān)測試代碼
base64編碼相關(guān)的代碼
base64.h頭文件
#ifndef BASE64_H
#define BASE64_H
#include
#include
#include
#include
#include
#include
int base64_encode( const unsigned char * bindata, int binlength, char * base64);
int base64_decode( const char * base64, unsigned char * bindata );
#endif
base64.c
#include "base64.h"
#ifndef MAX_PATH
#define MAX_PATH 256
#endif
const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int base64_encode( const unsigned char * bindata, int binlength, char * base64)
{
int i, j;
unsigned char current;
for ( i = 0, j = 0 ; i < binlength ; i += 3 )
{
current = (bindata[i] >> 2) ;
current &= (unsigned char)0x3F;
base64[j++] = base64char[(int)current];
current = ( (unsigned char)(bindata[i] << 4 ) ) & ( (unsigned char)0x30 ) ;
if ( i + 1 >= binlength )
{
base64[j++] = base64char[(int)current];
base64[j++] = '=';
base64[j++] = '=';
break;
}
current |= ( (unsigned char)(bindata[i+1] >> 4) ) & ( (unsigned char) 0x0F );
base64[j++] = base64char[(int)current];
current = ( (unsigned char)(bindata[i+1] << 2) ) & ( (unsigned char)0x3C ) ;
if ( i + 2 >= binlength )
{
base64[j++] = base64char[(int)current];
base64[j++] = '=';
break;
}
current |= ( (unsigned char)(bindata[i+2] >> 6) ) & ( (unsigned char) 0x03 );
base64[j++] = base64char[(int)current];
current = ( (unsigned char)bindata[i+2] ) & ( (unsigned char)0x3F ) ;
base64[j++] = base64char[(int)current];
}
base64[j] = '\0';
return j;
}
int base64_decode( const char * base64, unsigned char * bindata )
{
int i, j;
unsigned char k;
unsigned char temp[4];
for ( i = 0, j = 0; base64[i] != '\0' ; i += 4 )
{
memset( temp, 0xFF, sizeof(temp) );
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i] )
temp[0]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+1] )
temp[1]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+2] )
temp[2]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+3] )
temp[3]= k;
}
bindata[j++] = ((unsigned char)(((unsigned char)(temp[0] << 2))&0xFC)) |
((unsigned char)((unsigned char)(temp[1]>>4)&0x03));
if ( base64[i+2] == '=' )
break;
bindata[j++] = ((unsigned char)(((unsigned char)(temp[1] << 4))&0xF0)) |
((unsigned char)((unsigned char)(temp[2]>>2)&0x0F));
if ( base64[i+3] == '=' )
break;
bindata[j++] = ((unsigned char)(((unsigned char)(temp[2] << 6))&0xF0)) |
((unsigned char)(temp[3]&0x3F));
}
return j;
}
簽名、驗(yàn)簽測試代碼
#include
#include
#include
#include
#include
#include
#include
#include
#include "base64.h"
int main ()
{
int err;
int sig_len;
unsigned char sig_buf [4096];
static char keyfile[] = "key.pem";
static char data[] = "3D2F0517-A9A8-49B6-BAEF-89C76934";
EVP_MD_CTX md_ctx;
EVP_PKEY * pkey;
FILE * fp;
X509 *x509;
ERR_load_crypto_strings();
fp = fopen (keyfile, "r");
if (fp == NULL) exit (1);
pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
fclose (fp);
if (pkey == NULL) {
ERR_print_errors_fp (stderr);
exit (1);
}
/* Do the signature */
EVP_SignInit (&md_ctx, EVP_sha256());
EVP_SignUpdate (&md_ctx, data, strlen(data));
sig_len = sizeof(sig_buf);
err = EVP_SignFinal (&md_ctx, sig_buf, (unsigned int *)&sig_len, pkey);
char base64[4096]={0};
base64_encode( sig_buf, sig_len, base64);
printf("base64 signed %s\n",base64);
//base64_decode( const char * base64, unsigned char * bindata );
if (err != 1) {
ERR_print_errors_fp(stderr);
exit (1);
}
EVP_PKEY_free (pkey);
char pemCert[]="-----BEGIN CERTIFICATE-----\n"
"MIICLDCCAdYCAQAwDQYJKoZIhvcNAQEEBQAwgaAxCzAJBgNVBAYTAlBUMRMwEQYD\n"
"VQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5ldXJv\n"
"bmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMTEmJy\n"
"dXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZpMB4X\n"
"DTk2MDkwNTAzNDI0M1oXDTk2MTAwNTAzNDI0M1owgaAxCzAJBgNVBAYTAlBUMRMw\n"
"EQYDVQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5l\n"
"dXJvbmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMT\n"
"EmJydXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZp\n"
"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNw\n"
"L4lYKbpzzlmC5beaQXeQ2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAATAN\n"
"BgkqhkiG9w0BAQQFAANBAFqPEKFjk6T6CKTHvaQeEAsX0/8YHPHqH/9AnhSjrwuX\n"
"9EBc0n6bVGhN7XaXd6sJ7dym9sbsWxb+pJdurnkxjx4=\n"
"-----END CERTIFICATE-----";
BIO * b = BIO_new_mem_buf(pemCert, strlen(pemCert));
if (NULL == b){
return -1001;
}
PEM_read_bio_X509(b, &x509, NULL, NULL);
if (NULL == x509){
BIO_free(b), b=NULL;
X509_free(x509), x509=NULL;
return -1002;
}
if (x509 == NULL) {
ERR_print_errors_fp(stderr);
exit(1);
}
printf("halo\n");
/* Get public key - eay */
pkey=X509_get_pubkey(x509);
if (pkey == NULL) {
ERR_print_errors_fp (stderr);
exit (1);
}
/* Verify the signature */
unsigned char aa[4096]={0};
int sin_length = base64_decode(base64,aa );
EVP_VerifyInit (&md_ctx, EVP_sha256());
EVP_VerifyUpdate (&md_ctx, data, strlen((char*)data));
err = EVP_VerifyFinal (&md_ctx, aa, sin_length, pkey);
EVP_PKEY_free (pkey);
if (err != 1) {
ERR_print_errors_fp (stderr);
exit (1);
}
printf ("Signature Verified Ok.\n");
return(0);
}
測試證書
公鑰證書-----BEGIN CERTIFICATE-----
MIICLDCCAdYCAQAwDQYJKoZIhvcNAQEEBQAwgaAxCzAJBgNVBAYTAlBUMRMwEQYD
VQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5ldXJv
bmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMTEmJy
dXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZpMB4X
DTk2MDkwNTAzNDI0M1oXDTk2MTAwNTAzNDI0M1owgaAxCzAJBgNVBAYTAlBUMRMw
EQYDVQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5l
dXJvbmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMT
EmJydXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZp
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNw
L4lYKbpzzlmC5beaQXeQ2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAATAN
BgkqhkiG9w0BAQQFAANBAFqPEKFjk6T6CKTHvaQeEAsX0/8YHPHqH/9AnhSjrwuX
9EBc0n6bVGhN7XaXd6sJ7dym9sbsWxb+pJdurnkxjx4=
-----END CERTIFICATE-----
私鑰證書
-----BEGIN RSA PRIVATE KEY-----
MIIBPAIBAAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNwL4lYKbpzzlmC5beaQXeQ
2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAAQJBALjkK+jc2+iihI98riEF
oudmkNziSRTYjnwjx8mCoAjPWviB3c742eO3FG4/soi1jD9A5alihEOXfUzloenr
8IECIQD3B5+0l+68BA/6d76iUNqAAV8djGTzvxnCxycnxPQydQIhAMXt4trUI3nc
a+U8YL2HPFA3gmhBsSICbq2OptOCnM7hAiEA6Xi3JIQECob8YwkRj29DU3/4WYD7
WLPgsQpwo1GuSpECICGsnWH5oaeD9t9jbFoSfhJvv0IZmxdcLpRcpslpeWBBAiEA
6/5B8J0GHdJq89FHwEG/H2eVVUYu5y/aD6sgcm+0Avg=
-----END RSA PRIVATE KEY-----
編譯用的makefile
CC=ccCFLAGS= -g -I../../include -WallLIBS= ./base64.o -L../.. -lcrypto -ldlEXAMPLES=signall: $(EXAMPLES)?sign: sign.o$(CC) -o sign sign.o $(LIBS)clean:rm -f $(EXAMPLES) *.otest: all./sign
總結(jié)
以上是生活随笔為你收集整理的php pkcs7签名验签算法,OpenSSL 签名验签接口调用及测试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: dede插件-包含SEO所有功能的ded
- 下一篇: dede flag php,织梦dede