您的位置:首页 > 运维架构 > Linux

解决linux c利用openssl进行3des和安卓封装的接口加密解密出的字符串不一样的问题

2017-11-03 17:04 701 查看
做项目中需要对密码进行加密,使用linux的openssl进行3des加密解密,发现加密出来的字符串和安卓封装的接口加密后的字符串不一样,之后发现是安卓端对加密出来的字符进行了base64编码,加上base64编码之后加密解密都正常了。


测试代码:

basetype.h

#ifndef _BASETYPE_H_
#define _BASETYPE_H_
#include <stdbool.h>
#include <stdarg.h>

typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;

typedef unsigned char  BOOL;

/* When building OpenTV, these types are defined in the OpenTV headers */
typedef unsigned long long u_int64;
typedef unsigned int u_int32;
typedef unsigned short u_int16;
typedef unsigned char u_int8;
typedef int sem_id_t;
#if !defined(TYPEDEF_H) /* Added to keep softmodem code common */
typedef signed long long int64;
typedef signed long int32;
typedef signed short int16;
typedef signed char int8;

/* Added to keep softmodem code common */
typedef unsigned long long uint64;
typedef unsigned long uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;
#endif /* !defined(TYPEDEF_H) */

typedef unsigned char           UINT8;
typedef unsigned int            UINT16;
typedef unsigned long           UINT32;
typedef signed long INT32;
typedef int                 INT;         ///<Not in v2.0. Borrow the name from uITRON 3.0 and later
typedef unsigned long   DWORD;
typedef unsigned short  WORD;
typedef unsigned char  BYTE;

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#ifndef true
#define true 1
#endif

#ifndef false
#define false 0
#endif

#ifndef NULL
#define NULL    0
#endif
typedef  signed short           SHORT;
typedef  unsigned short     USHORT;
typedef  long                   LONG;
typedef  unsigned long          ULONG;
typedef  unsigned int           UINT;
typedef unsigned char  U8;
typedef unsigned short  U16;
typedef unsigned int    U32;
typedef signed int S32;
/* Common signed types */
typedef  signed char    S8;
typedef float           FLOAT;
typedef FLOAT           *PFLOAT;
typedef unsigned int    *PUINT;

typedef unsigned char       u8;
typedef signed char         s8;
typedef unsigned short int  u16;
typedef signed short int    s16;
typedef unsigned int        u32;
typedef signed int          s32;

#endif /* _BASETYPE_H_ */


base64.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char base64char[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char *base64_encode(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++] = 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 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 (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;
}


ssl_3des.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <openssl/des.h>

#include "basetype.h"

#define KEY_SIZE (24)
int encrypt_3des_ecb3(U8 *in, U8 *out, S8 *key)
{
DES_key_schedule ks1, ks2, ks3;
S8 acKey[KEY_SIZE];
int iIndex = 0;
int len = 0;
int nlen = 0;
char ch = '\0';
U8 src[1024] = {0};

memset(acKey, 0, sizeof(acKey));
len = strlen((char *)key);
for(iIndex = 0; iIndex < len; iIndex++)
{
acKey[iIndex] = key[iIndex];
}
for(; iIndex < sizeof(acKey); iIndex++)
{
acKey[iIndex] = 0x0;
}

DES_set_key_unchecked((C_Block *)(&acKey[0]), &ks1);
DES_set_key_unchecked((C_Block *)(&acKey[8]), &ks2);
DES_set_key_unchecked((C_Block *)(&acKey[16]), &ks3);

nlen = strlen((char *)in);
memcpy(src, in, nlen);
len = (nlen / 8 + (nlen % 8 ? 1 : 0)) * 8;

ch = 8 - nlen % 8;
memset(src + nlen, ch, (8 - nlen % 8) % 8);
for(iIndex = 0; iIndex < len; iIndex += 8)
{
DES_ecb3_encrypt((C_Block *)(src + iIndex), (C_Block *)(out + iIndex), &ks1, &ks2, &ks3, DES_ENCRYPT);
}

return 0;
}

int decrypt_3des_ecb3(U8 *in, U8 *out, S8 *key)
{
DES_key_schedule ks1, ks2, ks3;
S8 acKey[KEY_SIZE];
int iIndex = 0;
int len = 0;
int nlen = 0;
char ch = '\0';
U8 src[1024] = {0};

memset(acKey, 0, sizeof(acKey));
len = strlen((char *)key);
for(iIndex = 0; iIndex < len; iIndex++)
{
acKey[iIndex] = key[iIndex];
}
for(; iIndex < sizeof(acKey); iIndex++)
{
acKey[iIndex] = 0x0;
}

DES_set_key_unchecked((C_Block *)(&acKey[0]), &ks1);
DES_set_key_unchecked((C_Block *)(&acKey[8]), &ks2);
DES_set_key_unchecked((C_Block *)(&acKey[16]), &ks3);

nlen = strlen((char *)in);
memcpy(src, in, nlen);
len = (nlen / 8 + (nlen % 8 ? 1 : 0)) * 8;

ch = 8 - nlen % 8;
memset(src + nlen, ch, (8 - nlen % 8) % 8);
for(iIndex = 0; iIndex < len; iIndex += 8)
{
DES_ecb3_encrypt((C_Block *)(src + iIndex), (C_Block *)(out + iIndex), &ks1, &ks2, &ks3, DES_DECRYPT);
}

return 0;
}


test.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "basetype.h"

extern int decrypt_3des_ecb3(U8 *in, U8 *out, S8 *key);
extern int encrypt_3des_ecb3(U8 *in, U8 *out, S8 *key);

extern char *base64_encode(unsigned char *bindata, char * base64, int binlength);
extern int base64_decode(const char * base64, unsigned char * bindata);

int main(void)
{
S8 message[] = "test123";
S8 gucKey[] = {0x11, 0x22, 0x4F, 0x58, 0x88, 0x10, 0x40, 0x38, 0x28, 0x25, 0x79, 0x51, 0xCB, 0xDD, 0x55, 0x66, 0x77, 0x29, 0x74, 0x98, 0x30, 0x40, 0x36, 0xE2};
S8 outmessage[1024];
S8 tmp[1024];

printf("使用ssl ecb3加密\n");
memset(outmessage, 0, sizeof(outmessage));
encrypt_3des_ecb3((U8 *)message, (U8 *)outmessage, gucKey);
printf("加密后:%s\n", outmessage);

memset(tmp, 0, sizeof(tmp));
base64_encode((U8 *)outmessage, (char *)tmp, strlen((char *)outmessage));
printf("base64_encode:%s\n", tmp);

memset(outmessage, 0, sizeof(outmessage));
base64_decode((const char *)tmp, (unsigned char *)outmessage);
printf("base64_decode:%s\n", outmessage);

memset(tmp, 0, sizeof(tmp));
decrypt_3des_ecb3((U8 *)outmessage, (U8 *)tmp, gucKey);
printf("解密后:%s\n", tmp);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐