【数据加密】使用XXTEA对NSData进行加密

来源:互联网 发布:mysql update replace 编辑:程序博客网 时间:2024/05/16 01:49
最近做的项目中数据传输要加密,开始使用的是AES加密算法,这个是本来就有高手封装好了的,在ios中对NSData进行加密,拿来直接用就ok了。但是考虑到传输数据大,频率高,服务器每秒可能要跟N多的用户交互,于是另寻它径。
后来了解到XXTEA效率挺高的,测试了一下加密解密可以保证在1毫秒之内完成。ok,就是它了。XXTEA加密算法是对TEA加密算法的升级,仍然是用128位(16字节)的密钥对64位(8字节)信息进行加密,也就是说加密的数据必须是8字节的整数倍,不够的话自动补齐。
不过,XXTEA是C语言实现的,当然没法传递NSData进行加密。网上找了N久,但是好像没有人给出现成的封装方法对NSData加密,只能自己封装了。
直接上代码:
XXTEA的C语言实现:(最原始的代码)
#define MX (z>>5^y<<2) + (y>>3^z<<4)^(sum^y) + (k[p&3^e]^z);  long btea(long* v, long n, long* k) {    unsigned long z=v[n-1], y=v[0], sum=0, e, DELTA=0x9e3779b9;    long p, q ;    if (n > 1) {          /* Coding Part */      q = 6 + 52/n;      while (q-- > 0) {        sum += DELTA;        e = (sum >> 2) & 3;        for (p=0; p<n-1; p++) y = v[p+1], z = v[p] += MX;        y = v[0];        z = v[n-1] += MX;      }      return 0 ;    } else if (n < -1) {  /* Decoding Part */      n = -n;      q = 6 + 52/n;      sum = q*DELTA ;      while (sum != 0) {        e = (sum >> 2) & 3;        for (p=n-1; p>0; p--) z = v[p-1], y = v[p] -= MX;        z = v[n-1];        y = v[0] -= MX;        sum -= DELTA;      }      return 0;    }    return 1;  }
封装后的程序
**********************************XXTEA.h***********************************/** 此类是对XXTEA官方算法进行的封装,XXTEA信息详见http://en.wikipedia.org/wiki/XXTEA*/#ifndef XXTEA_h#define XXTEA_h#include "stdlib.h"#include "stdio.h"#include <string.h>#ifndef XXTEA_TYPE#define XXTEA_TYPE int         // 一种32位长的数据类型,因int在32bit和64bit系统中都是32位的,故直接用int#endifclass XXTEA {public:    XXTEA();    ~XXTEA();   public:    /**     *     @brief     获得输出缓冲区的长度     *     *     @param      nLength      输入缓冲区长度     *     @param      isEncode      TRUE 即为加密,FALSE即为解密     *     *     @return     返回所需长度     */    static size_t XXTEAGetBufferLength(size_t nLength, bool isEncode);       /**     *     @brief     对数据流进行加密     *     *     @param      lpDstBuffer      目标缓冲区     *     @param      lpSrcBuffer      源缓冲区     *     @param      nLength      源缓冲区长度     *     @param      lpKey      密钥     *     *     @return     加密是否成功     */    static bool XXTEAEncode(char* lpDstBuffer, const char* lpSrcBuffer, size_t nLength, const XXTEA_TYPE* lpKey);    /**     *     @brief     对数据流进行解密     *     *     @param      lpDstBuffer      目标缓冲区     *     @param      lpSrcBuffer      源缓冲区     *     @param      nLength      源缓冲区长度     *     @param      lpKey      密钥     *     *     @return     解密是否成功     */    static bool XXTEADecode(char* lpDstBuffer, const char* lpSrcBuffer, size_t nLength, const XXTEA_TYPE* lpKey);   private:    /**     *     @brief     XXTEA官方算法,此类即是对其进行封装,详见http://en.wikipedia.org/wiki/XXTEA     *     *     @param      v      加解密数据流     *     @param      n      加解密长度,n > 1为加密,n < -1为解密     *     @param      k      密钥      注意:形式参数k需和MX中的k对应     *     *     @return     返回0表示加解密成功,返回1表示失败     */    static long btea(XXTEA_TYPE* v, long n, const XXTEA_TYPE* k);    /**     *     @brief     正常字符串以16进制保存     *     *     @param      surBuffer      源缓冲区     *     @param      length      源缓冲区长度     *     @param      dstBuffer      目标缓冲区     */    static void StringToHex(const char* surBuffer, int length, char* dstBuffer);    /**     *     @brief     16进制字符串解析成正常字符串     *     *     @param      surBuffer      源缓冲区     *     @param      dstBuffer      目标缓冲区     *     *     @return     目标缓冲区的长度     */    static int HexToString(const char* surBuffer,  char* dstBuffer);};#endif**********************************XXTEA.cpp*********************************#include "XXTEA.h"#define     MX      (z>>5^y<<2) + (y>>3^z<<4)^(sum^y) + (k[p&3^e]^z);#define     XXTEA_ALIGNMENT_BYTES                 4XXTEA::XXTEA(){   }XXTEA::~XXTEA(){   }size_t XXTEA::XXTEAGetBufferLength(size_t nLength, bool isEncode){    if (isEncode) {        size_t nSize = nLength / XXTEA_ALIGNMENT_BYTES + (nLength % XXTEA_ALIGNMENT_BYTES  ? 1 : 0);        return (nSize * XXTEA_ALIGNMENT_BYTES * 2 + 1);    }    else {        return (nLength / 2 + 1);    }}bool XXTEA::XXTEAEncode(char* lpDstBuffer, const char* lpSrcBuffer, size_t nLength, const XXTEA_TYPE* lpKey){    long ret = 1;    if (nLength > XXTEA_ALIGNMENT_BYTES && lpDstBuffer && lpSrcBuffer) {        size_t nSize = nLength / XXTEA_ALIGNMENT_BYTES + (nLength % XXTEA_ALIGNMENT_BYTES  ? 1 : 0);        char* data = (char*)malloc(nSize * XXTEA_ALIGNMENT_BYTES * 2);        memset(data, 0, nSize * XXTEA_ALIGNMENT_BYTES * 2);        memcpy(data, lpSrcBuffer, nLength);        ret = btea((XXTEA_TYPE*)data, nSize, lpKey);        memset(lpDstBuffer, 0, XXTEAGetBufferLength(nLength, true));        StringToHex(data, (int)nSize * XXTEA_ALIGNMENT_BYTES, lpDstBuffer);        free(data);    }    return (ret == 0);}bool XXTEA::XXTEADecode(char* lpDstBuffer, const char* lpSrcBuffer, size_t nLength, const XXTEA_TYPE* lpKey){    long ret = 1;    if (nLength > XXTEA_ALIGNMENT_BYTES * 2 && lpDstBuffer && lpSrcBuffer) {        size_t nSize = XXTEAGetBufferLength(nLength, false);        memset(lpDstBuffer, 0, nSize);        HexToString(lpSrcBuffer, lpDstBuffer);        ret = btea((XXTEA_TYPE*)lpDstBuffer, -((nSize - 1)/ XXTEA_ALIGNMENT_BYTES), lpKey);    }    return (ret == 0);}long XXTEA::btea(XXTEA_TYPE* v, long n, const XXTEA_TYPE* k) {    unsigned XXTEA_TYPE z, y;    unsigned long sum = 0, e, DELTA = 0x9e3779b9;    long p, q;    if (n > 1) {          /* Coding Part */        z = v[n-1];        q = 6 + 52 / n;        while (q-- > 0) {            sum += DELTA;            e = (sum >> 2) & 3;            for (p = 0; p < n-1; ++p) y = v[p+1], z = v[p] += MX;            y = v[0];            z = v[n-1] += MX;        }        return 0;    } else if (n < -1) {  /* Decoding Part */        y = v[0];        n = -n;        q = 6 + 52 / n;        sum = q * DELTA ;        while (sum != 0) {            e = (sum >> 2) & 3;            for (p = n-1; p > 0; --p) z = v[p-1], y = v[p] -= MX;            z = v[n-1];            y = v[0] -= MX;            sum -= DELTA;        }        return 0;    }    return 1;}void XXTEA::StringToHex(const char* surBuffer, int length, char* dstBuffer){    for (int i = 0; i < length; i++)    {        sprintf(&dstBuffer[2*i], "%02X", (unsigned char)surBuffer[i]);    }    dstBuffer[2 * length] = '\0';}int XXTEA::HexToString(const char* surBuffer,  char* dstBuffer){    size_t length = strlen((char*)surBuffer) ;    for(int i = 0; i < length/2; i++)    {        int temp;        sscanf(&surBuffer[2 * i], "%02X", &temp);        dstBuffer[i] = (char)temp;    }    dstBuffer[length/2] = '\0';    return (int)strlen((char*)dstBuffer);}********************************XXTEAHELP.h********************************#import <Foundation/Foundation.h>@interface XXTEAHELP : NSObject{   }+(NSData*) encodeWithData:(NSData *)data;+(NSData*) decodeWithData:(NSData *)data;@end********************************XXTEAHELP.mm*******************************#import "XXTEAHELP.h"#include "XXTEA.h"@implementation XXTEAHELP+(NSData*) encodeWithData:(NSData *)data{    char *ch = (char *)[data bytes];    size_t length = XXTEA::XXTEAGetBufferLength(strlen(ch) + 1, true);    char* encodeBuffer = new char[length];    XXTEA_TYPE key[4] = {0x12345678, 0x734a67fc, 0x3367a642, 0x78432562};    XXTEA::XXTEAEncode(encodeBuffer, ch, strlen(ch) +1, key);    void *buffer = (void *)encodeBuffer;    data = [NSData dataWithBytes:buffer length:3*(strlen(ch)+1)];       return data;}+(NSData*) decodeWithData:(NSData *)data{    XXTEA_TYPE key[4] = {0x12345678, 0x734a67fc, 0x3367a642, 0x78432562};    const char *en = (const char *)[data bytes];    size_t length = XXTEA::XXTEAGetBufferLength((strlen(en) + 1)/2, true);    char *de = new char[XXTEA::XXTEAGetBufferLength(length, false)];    XXTEA::XXTEADecode(de, en, length, key);    void *buf = (void *)de;    data = [NSData dataWithBytes:buf length:strlen(de)+1];       return data;}********************************使用方法*******************************    NSString *str = @"Hello World!hogablgsjlwobg1025";    NSMutableData *data = [[NSMutableData alloc] init];    [data appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];    NSLog(@"加密前:~~~~~~~~~~~~~ %@",data);    data = (NSMutableData *)[XXTEAHELP encodeWithData:data];    NSLog(@"加密后:~~~~~~~~~~~~~ %@",data);    data = (NSMutableData *)[XXTEAHELP decodeWithData:data];    NSLog(@"解密后:~~~~~~~~~~~~~ %@",data);    NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];


原创粉丝点击