Encryption.h文件
#import <Foundation/Foundation.h>
@class NSString;
@interface NSData (Encryption)
- (NSData *)AES256EncryptWithKey:(NSString *)key; //加密
- (NSData *)AES256DecryptWithKey:(NSString *)key; //解密
- (NSString *)newStringInBase64FromData; //追加64编码
+ (NSString*)base64encode:(NSString*)str; //同上64编码
@end
------------------------------------------------------------------------------------------------
Encryption.m文件
#import "Encryption.h"
#import <CommonCrypto/CommonCryptor.h>
static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@implementation NSData (Encryption)
- (NSData *)AES256EncryptWithKey:(NSString *)key {
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer); //free the buffer;
return nil;
}
- (NSData *)AES256DecryptWithKey:(NSString *)key {
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer); //free the buffer;
return nil;
}
- (NSString *)newStringInBase64FromData //追加64编码
{
NSMutableString *dest = [[NSMutableString alloc] initWithString:@""];
unsigned char * working = (unsigned char *)[self bytes];
int srcLen = [self length];
for (int i=0; i<srcLen; i += 3) {
for (int nib=0; nib<4; nib++) {
int byt = (nib == 0)?0:nib-1;
int ix = (nib+1)*2;
if (i+byt >= srcLen) break;
unsigned char curr = ((working[i+byt] << (8-ix)) & 0x3F);
if (i+nib < srcLen) curr |= ((working[i+nib] >> ix) & 0x3F);
[dest appendFormat:@"%c", base64[curr]];
}
}
return dest;
}
+ (NSString*)base64encode:(NSString*)str
{
if ([str length] == 0)
return @"";
const char *source = [str UTF8String];
int strlength = strlen(source);
char *characters = malloc(((strlength + 2) / 3) * 4);
if (characters == NULL)
return nil;
NSUInteger length = 0;
NSUInteger i = 0;
while (i < strlength) {
char buffer[3] = {0,0,0};
short bufferLength = 0;
while (bufferLength < 3 && i < strlength)
buffer[bufferLength++] = source[i++];
characters[length++] = base64[(buffer[0] & 0xFC) >> 2];
characters[length++] = base64[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
if (bufferLength > 1)
characters[length++] = base64[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
else characters[length++] = '=';
if (bufferLength > 2)
characters[length++] = base64[buffer[2] & 0x3F];
else characters[length++] = '=';
}
NSString *g = [[[NSString alloc] initWithBytesNoCopy:characters length:lengthencoding:NSASCIIStringEncoding freeWhenDone:YES] autorelease];
return g;
}
@end
------------------------------------------------------------------------------------------------
测试代码
#import "Encryption.h"
NSString *key = @"my password";
NSString *secret = @"text to encrypt";
//加密
NSData *plain = [secret dataUsingEncoding:NSUTF8StringEncoding];
NSData *cipher = [plain AES256EncryptWithKey:key];
NSLog(@"%@",[[cipher newStringInBase64FromData] autorelease]);
printf("%s\n", [[cipher description] UTF8String]);
NSLog(@"%@", [[[NSString alloc] initWithData:cipher encoding:NSUTF8StringEncoding] autorelease]);//打印出null,这是因为没有解密。
//解密
plain = [cipher AES256DecryptWithKey:key];
printf("%s\n", [[plain description] UTF8String]);
NSLog(@"%@", [[[NSString alloc] initWithData:plain encoding:NSUTF8StringEncoding] autorelease]);
//打印出secret的内容,用密码解密过了。如果使用错误的密码,则打印null
i am new in Objective c.My problem is how to convert image to Byte array[Encoding].Similarly how to convert Byte array to Image[Decoding]...In C i am using the Following code for Encoding and Decoding purpose...
#include <stdio.h>
#include <stdlib.h>
/*
** Translation Table as described in RFC1113
*/
static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz0123456789+/";
/*
** Translation Table to decode (created by author)
*/
static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW $$$$$$XYZ[\\]^_`abcdefghijklmnopq";
/*
** encodeblock
**
** encode 3 8-bit binary bytes as 4 '6-bit' characters
*/
void encodeblock( unsigned char in[3], unsigned char out[4], int len )
{
out[0] = cb64[ in[0] >> 2 ];
out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');
out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '=');
}
/*
** encode
**
** base64 encode a stream adding padding and line breaks as per spec.
*/
void encode( FILE *infile, FILE *outfile, int linesize )
{
unsigned char in[3], out[4];
int i, len, blocksout = 0;
while( !feof( infile ) ) {
len = 0;
for( i = 0; i < 3; i++ ) {
in[i] = (unsigned char) getc( infile );
if( !feof( infile ) ) {
len++;
}
else {
in[i] = 0;
}
}
if( len ) {
encodeblock( in, out, len );
for( i = 0; i < 4; i++ ) {
putc( out[i], outfile );
}
blocksout++;
}
if( blocksout >= (linesize/4) || feof( infile ) ) {
if( blocksout ) {
fprintf( outfile, "\r\n" );
}
blocksout = 0;
}
}
}
/*
** decodeblock
**
** decode 4 '6-bit' characters into 3 8-bit binary bytes
*/
void decodeblock( unsigned char in[4], unsigned char out[3] )
{
out[ 0 ] = (unsigned char ) (in[0] << 2 | in[1] >> 4);
out[ 1 ] = (unsigned char ) (in[1] << 4 | in[2] >> 2);
out[ 2 ] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]);
}
/*
** decode
**
** decode a base64 encoded stream discarding padding, line breaks and noise
*/
void decode( FILE *infile, FILE *outfile )
{
unsigned char in[4], out[3], v;
int i, len;
while( !feof( infile ) ) {
for( len = 0, i = 0; i < 4 && !feof( infile ); i++ ) {
v = 0;
while( !feof( infile ) && v == 0 ) {
v = (unsigned char) getc( infile );
v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]);
if( v ) {
v = (unsigned char) ((v == '$') ? 0 : v - 61);
}
}
if( !feof( infile ) ) {
len++;
if( v ) {
in[ i ] = (unsigned char) (v - 1);
}
}
else {
in[i] = 0;
}
}
if( len ) {
decodeblock( in, out );
for( i = 0; i < len - 1; i++ ) {
putc( out[i], outfile );
}
}
}
}
But i don't know in objective c...Pls help me to sort out this issue...
Thanks
jayaprakash S