解决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; }
相关文章推荐
- 利用openssl进行BASE64编码解码、md5/sha1摘要、AES/DES3加密解密
- 实用命令:利用openssl进行BASE64编码解码、md5/sha1摘要、AES/DES3加密解密
- 一种另类的解决URL中文乱码问题--对中文进行加密、解密处理
- 利用openssl进行RSA加密解密
- 一种另类的解决URL中文乱码问题--对中文进行加密、解密处理
- 解决URL中文乱码问题--对中文进行加密、解密处理
- 利用Java API对字符串进行加密解密(DES加密算法)
- 利用openssl进行RSA加密解密实例
- 实用命令:利用openssl进行BASE64编码解码、md5/sha1摘要、AES/DES3加密解密
- 实用命令:利用openssl进行BASE64编码解码、md5/sha1摘要、AES/DES3加密解密
- 利用 BASE64Encoder 对字符串进行加密 BASE64Decoder进行解密
- 利用openssl进行RSA加密解密
- JAVA利用RSA加密算法的长度限制问题解决方案注意: RSA加密明文最大长度117字节,解密要求密文最大长度为128字节,所以在加密和解密的过程中需要分块进行。 RSA加密对明文的长度是有限制的,如
- 实用命令:利用openssl进行BASE64编码解码、md5/sha1摘要、AES/DES3加密解密
- 实用命令:利用openssl进行BASE64编码解码、md5/sha1摘要、AES/DES3加密解密
- 利用openssl进行BASE64编码解码、md5/sha1摘要、AES/DES3加密解密
- 利用openssl进行RSA加密解密
- 一种另类的解决URL中文乱码问题--对中文进行加密、解密处理
- 探讨.NET Core数据进行3DES加密和解密问题
- JAVA安卓和C# 3DES加密解密的兼容性问题