先了解下 DES ECB模式
ECB模式:
优点:
1. 简单;
2. 有利于并行计算;
3. 误差不会被传递;
缺点:
1. 不能隐藏明文的模式;
2. 可能对明文进行主动攻击;
DES ECB(电子密本方式)其实非常简单,就是将数据按照8个字节一段进行DES加密或解密得到一段段的8个字节的密文或者明文,最后一段不足8个字节(一般补0或者F),按照需求补足8个字节进行计算(并行计算),之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。
CBC模式:
优点:
1. 不容易主动攻击,安全性好于ECB,是SSL、IPSec的标准;
缺点:
1. 不利于并行计算;
2. 误差传递;
3. 需要初始化向量IV;
DES CBC(密文分组链接方式)有点麻烦,它的实现机制使加密的各段数据之间有了联系。其实现的机理如下:
加密步骤如下:
1. 首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补位)
2. 第一组数据D1与初始化向量I异或后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)
3. 第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
4. 之后的数据以此类推,得到Cn
5. 按顺序连为C1C2C3......Cn即为加密结果。
首先贴出加密类的头文件:
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCryptor.h>
#import "ConverUtil.h"
#import "Constants.h"
@interface DES : NSObject
//加密
- (NSString *) encryptUseDES:(NSString *)plainText key:(NSString*)key;
//解密
-(NSString*) decryptUseDES:(NSString*)cipherText key:(NSString*)key;
@end
加密类的实现类:
#import "DES.h"
@implementation DES
//DES_IV 自己定义的一个字符串 八个字节 一定要是八个字节
-(Byte *) getIv{
NSString *testString = DES_IV;
NSData *testData = [testString dataUsingEncoding: NSUTF8StringEncoding];
// for(int i=0;i<[testData length];i++)
// printf("testByte = %d\n",testByte[i]);
return (Byte *)[testData bytes];
}
//plainText需加密 字符串 key 定义好的 加密 解密 钥匙
- (NSString *) encryptUseDES:(NSString *)plainText key:(NSString*)key{
Byte *iv=[self getIv];
// NSString *escape=[plainText stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
// return escape;
NSData* data=[plainText dataUsingEncoding: NSUTF8StringEncoding];
NSUInteger bufferSize=([data length] + kCCKeySizeDES) & ~(kCCKeySizeDES -1);
char buffer[bufferSize];
memset(buffer, 0,sizeof(buffer));
size_t bufferNumBytes;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmDES,
kCCOptionPKCS7Padding,
[key UTF8String],
kCCKeySizeDES,
iv ,
[data bytes],
[data length],
buffer,
bufferSize,
&bufferNumBytes);
if (cryptStatus ==kCCSuccess) {
NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)bufferNumBytes];
return [ConverUtil parseByteArray2HexString:[data bytes] count:bufferNumBytes] ;
// NSLog(@"objccipherTextBytes:%@",[XYDES dataToHex:data]);
// ciphertext = [GTMBase64 stringByEncodingData:data];
// NSLog(@"objccipherTextBase64:%@",ciphertext);
}
return nil;
}
-(NSString*) decryptUseDES:(NSString*)cipherText key:(NSString*)key{
Byte *iv=[self getIv];
NSData* data = [ConverUtil parseHexToByteArray:cipherText];
NSUInteger bufferSize=([data length] + kCCKeySizeDES) & ~(kCCKeySizeDES -1);
char buffer[bufferSize];
memset(buffer, 0,sizeof(buffer));
size_t bufferNumBytes;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmDES,
kCCOptionPKCS7Padding,
[key UTF8String],
kCCKeySizeDES,
iv,
[data bytes],
[data length],
buffer,
bufferSize,
&bufferNumBytes);
NSString* plainText = nil;
if (cryptStatus ==kCCSuccess) {
NSData *plainData =[NSData dataWithBytes:buffer length:(NSUInteger)bufferNumBytes];
plainText = [[NSString alloc] initWithData:plainData encoding:NSUTF8StringEncoding];
}
return plainText;
}
@end
下面是转码类,主要是16进制和字节的转化
头文件:
#import <Foundation/Foundation.h>
@interface ConverUtil : NSObject
/**
64编码
*/
+(NSString *)base64Encoding:(NSData*) text;
/**
字节转化为16进制数
*/
+(NSString *) parseByte2HexString:(Byte *) bytes;
/**
字节数组转化16进制数
*/
+(NSString *) parseByteArray2HexString:(Byte[]) bytes count:(int)count;
/*
将16进制数据转化成NSData 数组
*/
+(NSData*) parseHexToByteArray:(NSString*) hexString;
@end
实现类:
#import "ConverUtil.h"
@implementation ConverUtil
static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/**
64编码
*/
+(NSString *)base64Encoding:(NSData*) text
{
if (text.length == 0)
return @"";
char *characters = malloc(text.length*3/2);
if (characters == NULL)
return @"";
int end = text.length - 3;
int index = 0;
int charCount = 0;
int n = 0;
while (index <= end) {
int d = (((int)(((char *)[text bytes])[index]) & 0x0ff) << 16)
| (((int)(((char *)[text bytes])[index + 1]) & 0x0ff) << 8)
| ((int)(((char *)[text bytes])[index + 2]) & 0x0ff);
characters[charCount++] = encodingTable[(d >> 18) & 63];
characters[charCount++] = encodingTable[(d >> 12) & 63];
characters[charCount++] = encodingTable[(d >> 6) & 63];
characters[charCount++] = encodingTable[d & 63];
index += 3;
if(n++ >= 14)
{
n = 0;
characters[charCount++] = ' ';
}
}
if(index == text.length - 2)
{
int d = (((int)(((char *)[text bytes])[index]) & 0x0ff) << 16)
| (((int)(((char *)[text bytes])[index + 1]) & 255) << 8);
characters[charCount++] = encodingTable[(d >> 18) & 63];
characters[charCount++] = encodingTable[(d >> 12) & 63];
characters[charCount++] = encodingTable[(d >> 6) & 63];
characters[charCount++] = '=';
}
else if(index == text.length - 1)
{
int d = ((int)(((char *)[text bytes])[index]) & 0x0ff) << 16;
characters[charCount++] = encodingTable[(d >> 18) & 63];
characters[charCount++] = encodingTable[(d >> 12) & 63];
characters[charCount++] = '=';
characters[charCount++] = '=';
}
NSString * rtnStr = [[NSString alloc] initWithBytesNoCopy:characters length:charCount encoding:NSUTF8StringEncoding freeWhenDone:YES];
return rtnStr;
}
/**
字节转化为16进制数
*/
+(NSString *) parseByte2HexString:(Byte *) bytes
{
NSMutableString *hexStr = [[NSMutableString alloc]init];
int i = 0;
if(bytes)
{
while (bytes[i] != '\0')
{
NSString *hexByte = [NSString stringWithFormat:@"%x",bytes[i] & 0xff];///16进制数
if([hexByte length]==1)
[hexStr appendFormat:@"0%@", hexByte];
else
[hexStr appendFormat:@"%@", hexByte];
i++;
}
}
return hexStr;
}
/**
字节数组转化16进制数
*/
+(NSString *) parseByteArray2HexString:(Byte[]) bytes count:(int)count
{
NSMutableString *hexStr = [[NSMutableString alloc]init];
// int i = 0;
if(bytes)
{
// while (bytes[i] != '\0')
// {
// NSString *hexByte = [NSString stringWithFormat:@"%x",bytes[i] & 0xff];///16进制数
//
//
// if([hexByte length]==1)
// [hexStr appendFormat:@"0%@", hexByte];
// else
// [hexStr appendFormat:@"%@", hexByte];
//
// i++;
// }
for (int i=0;i< count;i++)
{
NSString *hexByte = [NSString stringWithFormat:@"%x",bytes[i] & 0xff];///16进制数
if([hexByte length]==1)
[hexStr appendFormat:@"0%@", hexByte];
else
[hexStr appendFormat:@"%@", hexByte];
// i++;
}
}
return [hexStr uppercaseString];
}
/*
将16进制数据转化成NSData 数组
*/
+(NSData*) parseHexToByteArray:(NSString*) hexString
{
int j=0;
Byte bytes[hexString.length];
for(int i=0;i<[hexString length];i++)
{
int int_ch; /// 两位16进制数转化后的10进制数
unichar hex_char1 = [hexString characterAtIndex:i]; 两位16进制数中的第一位(高位*16)
int int_ch1;
if(hex_char1 >= '0' && hex_char1 <='9')
int_ch1 = (hex_char1-48)*16; 0 的Ascll - 48
else if(hex_char1 >= 'A' && hex_char1 <='F')
int_ch1 = (hex_char1-55)*16; A 的Ascll - 65
else
int_ch1 = (hex_char1-87)*16; a 的Ascll - 97
i++;
unichar hex_char2 = [hexString characterAtIndex:i]; ///两位16进制数中的第二位(低位)
int int_ch2;
if(hex_char2 >= '0' && hex_char2 <='9')
int_ch2 = (hex_char2-48); 0 的Ascll - 48
else if(hex_char2 >= 'A' && hex_char1 <='F')
int_ch2 = hex_char2-55; A 的Ascll - 65
else
int_ch2 = hex_char2-87; a 的Ascll - 97
int_ch = int_ch1+int_ch2;
bytes[j] = int_ch; ///将转化后的数放入Byte数组里
j++;
}
NSData *newData = [[NSData alloc] initWithBytes:bytes length:hexString.length/2];
return newData;
}
@end