发送DES-base64编码的HTTP Post请求,并base64-DES解码返回消息

#include <stdio.h>  
#include <string.h>  
#include <string>
#include <iostream>
#include <sys/socket.h>  
#include <arpa/inet.h>  
#include <unistd.h>  
#include <netinet/in.h>  
#include <stdlib.h>  
#include <assert.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
 
#define MAXLINE 1024

const char base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 

int post(char *ip,int port,char *page,char *type,char *msg,char *result){
    int sockfd,n;  
    char recvline[MAXLINE];  
    struct sockaddr_in servaddr;  
	char content[4096];
	char content_page[50];
	sprintf(content_page,"POST %s HTTP/1.1\r\n",page);
	char content_host[50];
	sprintf(content_host,"HOST: %s:%d\r\n",ip,port);
	char content_type[50];
	sprintf(content_type,"Content-Type: %s\r\n",type);
	char content_len[50];
	sprintf(content_len,"Content-Length: %d\r\n\r\n",strlen(msg));
	sprintf(content,"%s%s%s%s%s",content_page,content_host,content_type,content_len,msg);
    if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)  
        printf("socket error\n");  
    bzero(&servaddr,sizeof(servaddr));  
    servaddr.sin_family = AF_INET;  
    servaddr.sin_port = htons(80);  
    if(inet_pton(AF_INET,ip,&servaddr.sin_addr) <= 0)  
        printf("inet_pton error\n");  
    if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0)  
        printf("connect error\n");  
    write(sockfd,content,strlen(content));  
//	printf("%s\n",content);
    while((n = read(sockfd,recvline,MAXLINE)) > 0)  
    {  
        recvline[n] = 0;  
		strcat(result,recvline);
		if(strstr(recvline,"\n0\r\n")!=NULL){
			break;
		}
	}  
	if(n < 0)  
		printf("read error\n");  
}

std::string desEncrypt(const std::string& source, const std::string& key)
{
	EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);
    int ret = EVP_EncryptInit_ex(&ctx, EVP_des_ecb(), NULL, (const unsigned char*)key.data(), NULL);
    assert(ret == 1);
    unsigned char* result = new unsigned char[source.length() + 64]; // 弄个足够大的空间
    int len1 = 0;
    ret = EVP_EncryptUpdate(&ctx, result, &len1, (const unsigned char*)source.data(), source.length());
    assert(ret == 1);
    int len2 = 0;
    ret = EVP_EncryptFinal_ex(&ctx, result+len1, &len2); 
    assert(ret == 1);
    ret = EVP_CIPHER_CTX_cleanup(&ctx);
    assert(ret == 1);
    std::string res((char*)result, len1+len2);
    delete[] result;
    return res;
}

std::string desDecrypt(const std::string& ciphertext, const std::string& key)
{
    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);
    int ret = EVP_DecryptInit_ex(&ctx, EVP_des_ecb(), NULL, (const unsigned char*)key.data(), NULL);
    assert(ret == 1);
    unsigned char* result = new unsigned char[ciphertext.length() + 64]; // 弄个足够大的空间
    int len1 = 0;
    ret = EVP_DecryptUpdate(&ctx, result, &len1, (const unsigned char*)ciphertext.data(), ciphertext.length());
    assert(ret == 1);
    int len2 = 0;
    ret = EVP_DecryptFinal_ex(&ctx, result+len1, &len2); 
    assert(ret == 1);
    ret = EVP_CIPHER_CTX_cleanup(&ctx);
    assert(ret == 1);
    std::string res((char*)result, len1+len2);
    delete[] result;
    return res;
}
char *base64_encode(const unsigned char* bindata, char* base64, int binlength) 
{ 
   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++] = base[(int)current];

        current = ( (unsigned char)(bindata[i] << 4 ) ) & ( (unsigned char)0x30 ) ;
        if ( i + 1 >= binlength )
        {
            base64[j++] = base[(int)current];
            base64[j++] = '=';
            base64[j++] = '=';
            break;
        }
        current |= ( (unsigned char)(bindata[i+1] >> 4) ) & ( (unsigned char) 0x0F );
        base64[j++] = base[(int)current];

        current = ( (unsigned char)(bindata[i+1] << 2) ) & ( (unsigned char)0x3C ) ;
        if ( i + 2 >= binlength )
        {
            base64[j++] = base[(int)current];
            base64[j++] = '=';
            break;
        }
        current |= ( (unsigned char)(bindata[i+2] >> 6) ) & ( (unsigned char) 0x03 );
        base64[j++] = base[(int)current];

        current = ( (unsigned char)bindata[i+2] ) & ( (unsigned char)0x3F ) ;
        base64[j++] = base[(int)current];
    }
    base64[j] = '\0';
    return base64;
}

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 ( base[k] == base64[i] )
                temp[0]= k;
        }
        for ( k = 0 ; k < 64 ; k ++ )
        {
            if ( base[k] == base64[i+1] )
                temp[1]= k;
        }
        for ( k = 0 ; k < 64 ; k ++ )
        {
            if ( base[k] == base64[i+2] )
                temp[2]= k;
        }
        for ( k = 0 ; k < 64 ; k ++ )
        {
            if ( base[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;
}

int demo(char* name, char* id, char* appid, char* key, char photo[]){
	char msg[1024];
	sprintf(msg,"{\"appid\": \"%s\",\"service\":\"wpho\",\"name\": \"%s\",\"cardno\": \"%s\"}",appid,name,id);
	int len = strlen(msg);
	
	std::string enc = desEncrypt(msg, key);
	
	unsigned char *msg_des = (unsigned char*)enc.data();

	char msg_base64[4096];
	len = enc.length();
	base64_encode((unsigned char*)msg_des,msg_base64,len);

	char ip[] = "192.168.0.1;
	int port = 80;
	char type[] = "application/json";
	char page[100];
	sprintf(page,"/demo.do");

	char result[1024*1000];
	
	post(ip,port,page,type,msg_base64,result);
	char *h_proto = strtok(result,"\n");
	char *h_server = strtok(NULL,"\n");
	char *h_data = strtok(NULL,"\n");
	char *h_ctype = strtok(NULL,"\n");
	char *h_encoding = strtok(NULL,"\n");
	char *h_connection = strtok(NULL,"\n");
	char *h_pragma = strtok(NULL,"\n");
	char *h_expires = strtok(NULL,"\n");
	char *h_cache = strtok(NULL,"\n");
	char *body_length = strtok(NULL,"\r\n");
	char *body = strtok(NULL,"\n");
	
	body[strlen(body)-1]='\0';
	
	unsigned char back_base64[1024*100];
	int bytes = base64_decode(body, back_base64); 

	std::string source((char*)back_base64, bytes); // 二进制数据

	std::string dec = desDecrypt(source, key);

	printf("%s",dec.c_str());

	return 0;
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值