首先要说明一下我所遇到的需要加密的数据:向服务器端发送用户名与密码进行portal认证,当然为了显示出专业性(扯淡的说),服务器提供商要求发送经过四层加密后的数据,分别是:
1、用户名、密码分别用Base64加密
2、用户名,密码和发送时间相加之后进行DES加密
3、对加密后的结果再进行一次Base64加密
4、最后把结果用RLENCODE 转化成UTF-8
这其中主要使用到Base64加密与DES加密,再就是数据转换,过程如下:
//分别对用户及密码进行Base64加密
NSString *BASE64userName = [GTMBase64 base64Encode:[Puser.username dataUsingEncoding: NSUTF8StringEncoding]];
NSString *BASE64password = [GTMBase64 base64Encode:[Puser.password dataUsingEncoding: NSUTF8StringEncoding]];
//串联用户及密码字符串
NSString *allStr = [NSString stringWithFormat:@"username=%@,password=%@,timestamp=%@",BASE64userName,BASE64password,[Util getCurrentDateTime]];
Airsource_Log_Debug(@”allStr = %@”,allStr);
//DES加密
NSData *allStrData = [allStr dataUsingEncoding: NSUTF8StringEncoding];
NSData *DESData = [EncryptUtil DESEncrypt:allStrData WithKey:Post_SHAREKEY];
//Base64加密
NSString *Base64DESStr = [GTMBase64 base64Encode:DESData];
//Airsource_Log_Debug(@”Base64DESStr = %@”,Base64DESStr);
//URLENCODE 转化成UTF-8
NSString *URLENCODEBase64DESStr = [Base64DESStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//Airsource_Log_Debug(@”URLENCODEBase64DESStr = %@”,URLENCODEBase64DESStr);
//串联加密后的所有字符串
NSString *ipStr = [localIPAddress localIPAddress];//获取本地IP
Airsource_Log_Debug(@”ipStr = %@”,ipStr );
strurl = [NSString stringWithFormat:@"%@%@%@&userip=%@&userPublicIp=%@&language=Chinese",strurl,userInfo,URLENCODEBase64DESStr,ipStr,ipStr];
Airsource_Log_Debug(@”strurl = %@”,strurl );
终于得到了最后需要发送的加密string了。
其中用到的加密方法:GTMBase64
#import “GTMBase64.h”
static const char *kBase64EncodeChars = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”;
static const char *kWebSafeBase64EncodeChars = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_”;
static const char kBase64PaddingChar = ‘=’;
static const char kBase64InvalidChar = 99;
@interface GTMBase64 (PrivateMethods)
+(NSData *)baseEncode:(const void *)bytes
length:(NSUInteger)length
charset:(const char *)charset
padded:(BOOL)padded;
@end
@implementation GTMBase64
//解密:
+ (NSData*) base64Decode:(NSString *)string
{
unsigned long ixtext, lentext;
unsigned char ch, inbuf[4], outbuf[4];
short i, ixinbuf;
Boolean flignore, flendtext = false;
const unsigned char *tempcstring;
NSMutableData *theData;
if (string == nil) {
return [NSData data];
}
ixtext = 0;
tempcstring = (const unsigned char *)[string UTF8String];
lentext = [string length];
theData = [NSMutableData dataWithCapacity: lentext];
ixinbuf = 0;
while (true) {
if (ixtext >= lentext){
break;
}
ch = tempcstring [ixtext++];
flignore = false;
if ((ch >= ‘A’) && (ch = ‘a’) && (ch = ’0′) && (ch ch = ch – ’0′ + 52;
} else if (ch == ‘+’) {
ch = 62;
} else if (ch == ‘=’) {
flendtext = true;
} else if (ch == ‘/’) {
ch = 63;
} else {
flignore = true;
}
if (!flignore) {
short ctcharsinbuf = 3;
Boolean flbreak = false;
if (flendtext) {
if (ixinbuf == 0) {
break;
}
if ((ixinbuf == 1) || (ixinbuf == 2)) {
ctcharsinbuf = 1;
} else {
ctcharsinbuf = 2;
}
ixinbuf = 3;
flbreak = true;
}
inbuf [ixinbuf++] = ch;
if (ixinbuf == 4) {
ixinbuf = 0;
outbuf[0] = (inbuf[0] << 2) | ((inbuf[1] & 0×30) >> 4);
outbuf[1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2);
outbuf[2] = ((inbuf[2] & 0×03) << 6) | (inbuf[3] & 0x3F);
for (i = 0; i < ctcharsinbuf; i++) {
[theData appendBytes: &outbuf[i] length: 1];
}
}
if (flbreak) {
break;
}
}
}
return theData;
}
//加密:
+ (NSString*) base64Encode:(NSData *)data
{
static char base64EncodingTable[64] = {
‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’, ‘I’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’, ‘O’, ‘P’,
‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’, ‘X’, ‘Y’, ‘Z’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’,
‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’, ‘p’, ‘q’, ‘r’, ‘s’, ‘t’, ‘u’, ‘v’,
‘w’, ‘x’, ‘y’, ‘z’, ’0′, ’1′, ’2′, ’3′, ’4′, ’5′, ’6′, ’7′, ’8′, ’9′, ‘+’, ‘/’
};
int length = [data length];
unsigned long ixtext, lentext;
long ctremaining;
unsigned char input[3], output[4];
short i, charsonline = 0, ctcopy;
const unsigned char *raw;
NSMutableString *result;
lentext = [data length];
if (lentext < 1)
return @”";
result = [NSMutableString stringWithCapacity: lentext];
raw = [data bytes];
ixtext = 0;
while (true) {
ctremaining = lentext – ixtext;
if (ctremaining break;
for (i = 0; i < 3; i++) {
unsigned long ix = ixtext + i;
if (ix < lentext) input[i] = raw[ix]; else input[i] = 0; } output[0] = (input[0] & 0xFC) >> 2;
output[1] = ((input[0] & 0×03) << 4) | ((input[1] & 0xF0) >> 4);
output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
output[3] = input[2] & 0x3F;
ctcopy = 4;
switch (ctremaining) {
case 1:
ctcopy = 2;
break;
case 2:
ctcopy = 3;
break;
}
for (i = 0; i < ctcopy; i++)
[result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
for (i = ctcopy; i < 4; i++) [result appendString: @"="]; ixtext += 3; charsonline += 4; if ((length > 0) && (charsonline >= length))
charsonline = 0;
}
return result;
}
@end
用到的加密方法:EncryptUtil(DES加密)
#import “EncryptUtil.h”
#import “CommonCrypto/CommonCryptor.h”
#import “GTMBase64.h”
@implementation EncryptUtil
//DES加密
+ (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[data bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
//DES解密
+ (NSData *)DESDecrypt:(NSData *)data WithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[data bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
@end
获取IP地址
+ (NSString *)localIPAddress
{
NSString *localIP = nil;
struct ifaddrs *addrs;
if (getifaddrs(&addrs)==0) {
const struct ifaddrs *cursor = addrs;
while (cursor != NULL) {
if (cursor->ifa_addr->sa_family == AF_INET && (cursor->ifa_flags & IFF_LOOPBACK) == 0)
{
//NSString *name = [NSString stringWithUTF8String:cursor->ifa_name];
//if ([name isEqualToString:@"en0"]) // Wi-Fi adapter
{
localIP = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)cursor->ifa_addr)->sin_addr)];
break;
}
}
cursor = cursor->ifa_next;
}
freeifaddrs(addrs);
}
return localIP;
1、用户名、密码分别用Base64加密
2、用户名,密码和发送时间相加之后进行DES加密
3、对加密后的结果再进行一次Base64加密
4、最后把结果用RLENCODE 转化成UTF-8
这其中主要使用到Base64加密与DES加密,再就是数据转换,过程如下:
//分别对用户及密码进行Base64加密
NSString *BASE64userName = [GTMBase64 base64Encode:[Puser.username dataUsingEncoding: NSUTF8StringEncoding]];
NSString *BASE64password = [GTMBase64 base64Encode:[Puser.password dataUsingEncoding: NSUTF8StringEncoding]];
//串联用户及密码字符串
NSString *allStr = [NSString stringWithFormat:@"username=%@,password=%@,timestamp=%@",BASE64userName,BASE64password,[Util getCurrentDateTime]];
Airsource_Log_Debug(@”allStr = %@”,allStr);
//DES加密
NSData *allStrData = [allStr dataUsingEncoding: NSUTF8StringEncoding];
NSData *DESData = [EncryptUtil DESEncrypt:allStrData WithKey:Post_SHAREKEY];
//Base64加密
NSString *Base64DESStr = [GTMBase64 base64Encode:DESData];
//Airsource_Log_Debug(@”Base64DESStr = %@”,Base64DESStr);
//URLENCODE 转化成UTF-8
NSString *URLENCODEBase64DESStr = [Base64DESStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//Airsource_Log_Debug(@”URLENCODEBase64DESStr = %@”,URLENCODEBase64DESStr);
//串联加密后的所有字符串
NSString *ipStr = [localIPAddress localIPAddress];//获取本地IP
Airsource_Log_Debug(@”ipStr = %@”,ipStr );
strurl = [NSString stringWithFormat:@"%@%@%@&userip=%@&userPublicIp=%@&language=Chinese",strurl,userInfo,URLENCODEBase64DESStr,ipStr,ipStr];
Airsource_Log_Debug(@”strurl = %@”,strurl );
终于得到了最后需要发送的加密string了。
其中用到的加密方法:GTMBase64
#import “GTMBase64.h”
static const char *kBase64EncodeChars = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”;
static const char *kWebSafeBase64EncodeChars = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_”;
static const char kBase64PaddingChar = ‘=’;
static const char kBase64InvalidChar = 99;
@interface GTMBase64 (PrivateMethods)
+(NSData *)baseEncode:(const void *)bytes
length:(NSUInteger)length
charset:(const char *)charset
padded:(BOOL)padded;
@end
@implementation GTMBase64
//解密:
+ (NSData*) base64Decode:(NSString *)string
{
unsigned long ixtext, lentext;
unsigned char ch, inbuf[4], outbuf[4];
short i, ixinbuf;
Boolean flignore, flendtext = false;
const unsigned char *tempcstring;
NSMutableData *theData;
if (string == nil) {
return [NSData data];
}
ixtext = 0;
tempcstring = (const unsigned char *)[string UTF8String];
lentext = [string length];
theData = [NSMutableData dataWithCapacity: lentext];
ixinbuf = 0;
while (true) {
if (ixtext >= lentext){
break;
}
ch = tempcstring [ixtext++];
flignore = false;
if ((ch >= ‘A’) && (ch = ‘a’) && (ch = ’0′) && (ch ch = ch – ’0′ + 52;
} else if (ch == ‘+’) {
ch = 62;
} else if (ch == ‘=’) {
flendtext = true;
} else if (ch == ‘/’) {
ch = 63;
} else {
flignore = true;
}
if (!flignore) {
short ctcharsinbuf = 3;
Boolean flbreak = false;
if (flendtext) {
if (ixinbuf == 0) {
break;
}
if ((ixinbuf == 1) || (ixinbuf == 2)) {
ctcharsinbuf = 1;
} else {
ctcharsinbuf = 2;
}
ixinbuf = 3;
flbreak = true;
}
inbuf [ixinbuf++] = ch;
if (ixinbuf == 4) {
ixinbuf = 0;
outbuf[0] = (inbuf[0] << 2) | ((inbuf[1] & 0×30) >> 4);
outbuf[1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2);
outbuf[2] = ((inbuf[2] & 0×03) << 6) | (inbuf[3] & 0x3F);
for (i = 0; i < ctcharsinbuf; i++) {
[theData appendBytes: &outbuf[i] length: 1];
}
}
if (flbreak) {
break;
}
}
}
return theData;
}
//加密:
+ (NSString*) base64Encode:(NSData *)data
{
static char base64EncodingTable[64] = {
‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’, ‘I’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’, ‘O’, ‘P’,
‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’, ‘X’, ‘Y’, ‘Z’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’,
‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’, ‘p’, ‘q’, ‘r’, ‘s’, ‘t’, ‘u’, ‘v’,
‘w’, ‘x’, ‘y’, ‘z’, ’0′, ’1′, ’2′, ’3′, ’4′, ’5′, ’6′, ’7′, ’8′, ’9′, ‘+’, ‘/’
};
int length = [data length];
unsigned long ixtext, lentext;
long ctremaining;
unsigned char input[3], output[4];
short i, charsonline = 0, ctcopy;
const unsigned char *raw;
NSMutableString *result;
lentext = [data length];
if (lentext < 1)
return @”";
result = [NSMutableString stringWithCapacity: lentext];
raw = [data bytes];
ixtext = 0;
while (true) {
ctremaining = lentext – ixtext;
if (ctremaining break;
for (i = 0; i < 3; i++) {
unsigned long ix = ixtext + i;
if (ix < lentext) input[i] = raw[ix]; else input[i] = 0; } output[0] = (input[0] & 0xFC) >> 2;
output[1] = ((input[0] & 0×03) << 4) | ((input[1] & 0xF0) >> 4);
output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
output[3] = input[2] & 0x3F;
ctcopy = 4;
switch (ctremaining) {
case 1:
ctcopy = 2;
break;
case 2:
ctcopy = 3;
break;
}
for (i = 0; i < ctcopy; i++)
[result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
for (i = ctcopy; i < 4; i++) [result appendString: @"="]; ixtext += 3; charsonline += 4; if ((length > 0) && (charsonline >= length))
charsonline = 0;
}
return result;
}
@end
用到的加密方法:EncryptUtil(DES加密)
#import “EncryptUtil.h”
#import “CommonCrypto/CommonCryptor.h”
#import “GTMBase64.h”
@implementation EncryptUtil
//DES加密
+ (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[data bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
//DES解密
+ (NSData *)DESDecrypt:(NSData *)data WithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[data bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
@end
获取IP地址
+ (NSString *)localIPAddress
{
NSString *localIP = nil;
struct ifaddrs *addrs;
if (getifaddrs(&addrs)==0) {
const struct ifaddrs *cursor = addrs;
while (cursor != NULL) {
if (cursor->ifa_addr->sa_family == AF_INET && (cursor->ifa_flags & IFF_LOOPBACK) == 0)
{
//NSString *name = [NSString stringWithUTF8String:cursor->ifa_name];
//if ([name isEqualToString:@"en0"]) // Wi-Fi adapter
{
localIP = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)cursor->ifa_addr)->sin_addr)];
break;
}
}
cursor = cursor->ifa_next;
}
freeifaddrs(addrs);
}
return localIP;
}