#pragma mark - md5 and sha1
//md5 encode
+ (NSString *)md5:(NSString*)str
{
const char *cStr = [str UTF8String];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, (unsigned int)strlen(cStr), digest );
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:@"%02X", digest[i]];
return output;
}
//sha1 encode
+ (NSString*)sha1:(NSString*)str
{
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
const char *cstr = [str cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:str.length];
CC_SHA1(data.bytes, (unsigned int)data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
[output appendFormat:@"%02X", digest[i]];
return output;
}
#pragma mark - Base64 Encode/Decoder
//static const uint8_t kKeyBytes[] = "123456789abcdef";
static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- (NSString *)base64EncodeData:(NSData*)dataToConvert
{
if ([dataToConvert length] == 0)
return @"";
char *characters = malloc((([dataToConvert length] + 2) / 3) * 4);
if (characters == NULL)
return nil;
NSUInteger length = 0;
NSUInteger i = 0;
while (i < [dataToConvert length])
{
char buffer[3] = {0,0,0};
short bufferLength = 0;
while (bufferLength < 3 && i < [dataToConvert length])
buffer[bufferLength++] = ((char *)[dataToConvert bytes])[i++];
// Encode the bytes in the buffer to four characters, including padding "=" characters if necessary.
characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2];
characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
if (bufferLength > 1)
characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
else characters[length++] = '=';
if (bufferLength > 2)
characters[length++] = encodingTable[buffer[2] & 0x3F];
else characters[length++] = '=';
}
return [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES];
}
- (NSData*)base64DecodeString:(NSString *)string
{
if (string == nil)
return nil;
//[NSException raise:NSInvalidArgumentException format:nil];
if ([string length] == 0)
return [NSData data];
static char *decodingTable = NULL;
if (decodingTable == NULL)
{
decodingTable = malloc(256);
if (decodingTable == NULL)
return nil;
memset(decodingTable, CHAR_MAX, 256);
NSUInteger i;
for (i = 0; i < 64; i++)
decodingTable[(short)encodingTable[i]] = i;
}
const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];
if (characters == NULL) // Not an ASCII string!
return nil;
char *bytes = malloc((([string length] + 3) / 4) * 3);
if (bytes == NULL)
return nil;
NSUInteger length = 0;
NSUInteger i = 0;
while (YES)
{
char buffer[4];
short bufferLength;
for (bufferLength = 0; bufferLength < 4; i++)
{
if (characters[i] == '\0')
break;
if (isspace(characters[i]) || characters[i] == '=')
continue;
buffer[bufferLength] = decodingTable[(short)characters[i]];
if (buffer[bufferLength++] == CHAR_MAX) // Illegal character!
{
free(bytes);
return nil;
}
}
if (bufferLength == 0)
break;
if (bufferLength == 1) // At least two characters are needed to produce one byte!
{
free(bytes);
return nil;
}
// Decode the characters in the buffer to bytes.
bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);
if (bufferLength > 2)
bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);
if (bufferLength > 3)
bytes[length++] = (buffer[2] << 6) | buffer[3];
}
realloc(bytes, length);
return [NSData dataWithBytesNoCopy:bytes length:length];
}
- (NSString *)base64String:(NSString *)text
{
if (text || text.length == 0) {
return @"";
}
NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
return [self base64EncodeData:data];
}
- (NSString *)fromBase64String:(NSString *)base64
{
if (base64 || base64.length == 0) {
return @"";
}
NSData *data = [self base64DecodeString:base64];
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
#pragma mark - AES,DES,RSA
@implementation NSData (Encryption)
- (NSData *)AES256EncryptWithKey:(NSString *)key {//加密
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
- (NSData *)AES256DecryptWithKey:(NSString *)key {//解密
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
- (NSData *)DESEncryptWithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
- (NSData *)DESDecryptWithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
- (NSData *)encryptDataRSAWithKey:(SecKeyRef)publickey padding:(SecPadding)padding error:(NSError **)err
{
size_t cipherBufferSize = SecKeyGetBlockSize(publickey);
uint8_t *cipherBuffer = NULL;
cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
memset((void *)cipherBuffer,0x0,cipherBufferSize);
int blockSize = cipherBufferSize-11;
int numBlock = (int)ceil([self length] / (double)blockSize);
NSMutableData *encryptedData = [[NSMutableData alloc] init];
for (int i=0; i<numBlock; i++) {
int bufferSize = MIN(blockSize,[self length]-i * blockSize);
NSData *buffer = [self subdataWithRange:NSMakeRange(i * blockSize, bufferSize)];
OSStatus status = SecKeyEncrypt(publickey, padding,
(const uint8_t *)[buffer bytes],
[buffer length], cipherBuffer,
&cipherBufferSize);
if (status == noErr) {
NSData *encryptedBytes = [[NSData alloc]
initWithBytes:(const void *)cipherBuffer
length:cipherBufferSize];
[encryptedData appendData:encryptedBytes];
} else {
if (err) {
*err = [NSError errorWithDomain:@"errorDomain" code:status userInfo:nil];
}
CSLog(@"encrypt:usingKey: Error: %d", status);
if (cipherBuffer) {
free(cipherBuffer);
}
return nil;
}
}
if (cipherBuffer) {
free(cipherBuffer);
}
CSLog(@"Encrypted text (%d bytes): %@", [encryptedData length], [encryptedData description]);
return encryptedData;
}
- (NSData *)dencryptStringRSAWithKey:(SecKeyRef)privateKey padding:(SecPadding)padding error:(NSError **)err
{
OSStatus sanityCheck = noErr;
size_t cipherBufferSize = 0;
size_t keyBufferSize = 0;
NSData * key = nil;
uint8_t * keyBuffer = NULL;
// Calculate the buffer sizes.
cipherBufferSize = SecKeyGetBlockSize(privateKey);
keyBufferSize = [self length];
// Allocate some buffer space. I don't trust calloc.
keyBuffer = malloc( keyBufferSize * sizeof(uint8_t) );
memset((void *)keyBuffer, 0x0, keyBufferSize);
// Decrypt using the private key.
sanityCheck = SecKeyDecrypt(privateKey,
padding,
(const uint8_t *)[self bytes],
cipherBufferSize,
keyBuffer,
&keyBufferSize
);
if (sanityCheck == noErr) {
// Build up plain text blob.
key = [NSData dataWithBytes:(const void *)keyBuffer length:(NSUInteger)keyBufferSize];
} else {
if (err) {
*err = [NSError errorWithDomain:@"errorDomain" code:sanityCheck userInfo:nil];
}
if (keyBuffer) free(keyBuffer);
return nil;
}
if (keyBuffer)
free(keyBuffer);
return key;
}
@end
//md5 encode
+ (NSString *)md5:(NSString*)str
{
const char *cStr = [str UTF8String];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, (unsigned int)strlen(cStr), digest );
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:@"%02X", digest[i]];
return output;
}
//sha1 encode
+ (NSString*)sha1:(NSString*)str
{
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
const char *cstr = [str cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:str.length];
CC_SHA1(data.bytes, (unsigned int)data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
[output appendFormat:@"%02X", digest[i]];
return output;
}
#pragma mark - Base64 Encode/Decoder
//static const uint8_t kKeyBytes[] = "123456789abcdef";
static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- (NSString *)base64EncodeData:(NSData*)dataToConvert
{
if ([dataToConvert length] == 0)
return @"";
char *characters = malloc((([dataToConvert length] + 2) / 3) * 4);
if (characters == NULL)
return nil;
NSUInteger length = 0;
NSUInteger i = 0;
while (i < [dataToConvert length])
{
char buffer[3] = {0,0,0};
short bufferLength = 0;
while (bufferLength < 3 && i < [dataToConvert length])
buffer[bufferLength++] = ((char *)[dataToConvert bytes])[i++];
// Encode the bytes in the buffer to four characters, including padding "=" characters if necessary.
characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2];
characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
if (bufferLength > 1)
characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
else characters[length++] = '=';
if (bufferLength > 2)
characters[length++] = encodingTable[buffer[2] & 0x3F];
else characters[length++] = '=';
}
return [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES];
}
- (NSData*)base64DecodeString:(NSString *)string
{
if (string == nil)
return nil;
//[NSException raise:NSInvalidArgumentException format:nil];
if ([string length] == 0)
return [NSData data];
static char *decodingTable = NULL;
if (decodingTable == NULL)
{
decodingTable = malloc(256);
if (decodingTable == NULL)
return nil;
memset(decodingTable, CHAR_MAX, 256);
NSUInteger i;
for (i = 0; i < 64; i++)
decodingTable[(short)encodingTable[i]] = i;
}
const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];
if (characters == NULL) // Not an ASCII string!
return nil;
char *bytes = malloc((([string length] + 3) / 4) * 3);
if (bytes == NULL)
return nil;
NSUInteger length = 0;
NSUInteger i = 0;
while (YES)
{
char buffer[4];
short bufferLength;
for (bufferLength = 0; bufferLength < 4; i++)
{
if (characters[i] == '\0')
break;
if (isspace(characters[i]) || characters[i] == '=')
continue;
buffer[bufferLength] = decodingTable[(short)characters[i]];
if (buffer[bufferLength++] == CHAR_MAX) // Illegal character!
{
free(bytes);
return nil;
}
}
if (bufferLength == 0)
break;
if (bufferLength == 1) // At least two characters are needed to produce one byte!
{
free(bytes);
return nil;
}
// Decode the characters in the buffer to bytes.
bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);
if (bufferLength > 2)
bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);
if (bufferLength > 3)
bytes[length++] = (buffer[2] << 6) | buffer[3];
}
realloc(bytes, length);
return [NSData dataWithBytesNoCopy:bytes length:length];
}
- (NSString *)base64String:(NSString *)text
{
if (text || text.length == 0) {
return @"";
}
NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
return [self base64EncodeData:data];
}
- (NSString *)fromBase64String:(NSString *)base64
{
if (base64 || base64.length == 0) {
return @"";
}
NSData *data = [self base64DecodeString:base64];
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
#pragma mark - AES,DES,RSA
@implementation NSData (Encryption)
- (NSData *)AES256EncryptWithKey:(NSString *)key {//加密
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
- (NSData *)AES256DecryptWithKey:(NSString *)key {//解密
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeAES128,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
- (NSData *)DESEncryptWithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
- (NSData *)DESDecryptWithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding | kCCOptionECBMode,
keyPtr, kCCBlockSizeDES,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
- (NSData *)encryptDataRSAWithKey:(SecKeyRef)publickey padding:(SecPadding)padding error:(NSError **)err
{
size_t cipherBufferSize = SecKeyGetBlockSize(publickey);
uint8_t *cipherBuffer = NULL;
cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
memset((void *)cipherBuffer,0x0,cipherBufferSize);
int blockSize = cipherBufferSize-11;
int numBlock = (int)ceil([self length] / (double)blockSize);
NSMutableData *encryptedData = [[NSMutableData alloc] init];
for (int i=0; i<numBlock; i++) {
int bufferSize = MIN(blockSize,[self length]-i * blockSize);
NSData *buffer = [self subdataWithRange:NSMakeRange(i * blockSize, bufferSize)];
OSStatus status = SecKeyEncrypt(publickey, padding,
(const uint8_t *)[buffer bytes],
[buffer length], cipherBuffer,
&cipherBufferSize);
if (status == noErr) {
NSData *encryptedBytes = [[NSData alloc]
initWithBytes:(const void *)cipherBuffer
length:cipherBufferSize];
[encryptedData appendData:encryptedBytes];
} else {
if (err) {
*err = [NSError errorWithDomain:@"errorDomain" code:status userInfo:nil];
}
CSLog(@"encrypt:usingKey: Error: %d", status);
if (cipherBuffer) {
free(cipherBuffer);
}
return nil;
}
}
if (cipherBuffer) {
free(cipherBuffer);
}
CSLog(@"Encrypted text (%d bytes): %@", [encryptedData length], [encryptedData description]);
return encryptedData;
}
- (NSData *)dencryptStringRSAWithKey:(SecKeyRef)privateKey padding:(SecPadding)padding error:(NSError **)err
{
OSStatus sanityCheck = noErr;
size_t cipherBufferSize = 0;
size_t keyBufferSize = 0;
NSData * key = nil;
uint8_t * keyBuffer = NULL;
// Calculate the buffer sizes.
cipherBufferSize = SecKeyGetBlockSize(privateKey);
keyBufferSize = [self length];
// Allocate some buffer space. I don't trust calloc.
keyBuffer = malloc( keyBufferSize * sizeof(uint8_t) );
memset((void *)keyBuffer, 0x0, keyBufferSize);
// Decrypt using the private key.
sanityCheck = SecKeyDecrypt(privateKey,
padding,
(const uint8_t *)[self bytes],
cipherBufferSize,
keyBuffer,
&keyBufferSize
);
if (sanityCheck == noErr) {
// Build up plain text blob.
key = [NSData dataWithBytes:(const void *)keyBuffer length:(NSUInteger)keyBufferSize];
} else {
if (err) {
*err = [NSError errorWithDomain:@"errorDomain" code:sanityCheck userInfo:nil];
}
if (keyBuffer) free(keyBuffer);
return nil;
}
if (keyBuffer)
free(keyBuffer);
return key;
}
@end