757 lines
26 KiB
Objective-C
757 lines
26 KiB
Objective-C
//
|
|
// CocoaSecurity.m
|
|
//
|
|
// Created by Kelp on 12/5/12.
|
|
// Copyright (c) 2012 Kelp http://kelp.phate.org/
|
|
// MIT License
|
|
//
|
|
|
|
#import "CocoaSecurity.h"
|
|
#import <CommonCrypto/CommonHMAC.h>
|
|
#import <CommonCrypto/CommonCryptor.h>
|
|
|
|
#pragma mark - CocoaSecurity
|
|
@implementation CocoaSecurity
|
|
|
|
|
|
#pragma mark - AES Encrypt
|
|
// default AES Encrypt, key -> SHA384(key).sub(0, 32), iv -> SHA384(key).sub(32, 16)
|
|
+ (CocoaSecurityResult *)aesEncrypt:(NSString *)data key:(NSString *)key
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs aesEncrypt:data key:key];
|
|
}
|
|
- (CocoaSecurityResult *)aesEncrypt:(NSString *)data key:(NSString *)key
|
|
{
|
|
CocoaSecurityResult * sha = [self sha384:key];
|
|
NSData *aesKey = [sha.data subdataWithRange:NSMakeRange(0, 32)];
|
|
NSData *aesIv = [sha.data subdataWithRange:NSMakeRange(32, 16)];
|
|
|
|
return [self aesEncrypt:data key:aesKey iv:aesIv];
|
|
}
|
|
#pragma mark AES Encrypt 128, 192, 256
|
|
+ (CocoaSecurityResult *)aesEncrypt:(NSString *)data hexKey:(NSString *)key hexIv:(NSString *)iv
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs aesEncrypt:data hexKey:key hexIv:iv];
|
|
}
|
|
+ (CocoaSecurityResult *)aesEncrypt:(NSString *)data key:(NSData *)key iv:(NSData *)iv
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs aesEncrypt:data key:key iv:iv];
|
|
}
|
|
+ (CocoaSecurityResult *)aesEncryptWithData:(NSData *)data key:(NSData *)key iv:(NSData *)iv
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs aesEncryptWithData:data key:key iv:iv];
|
|
}
|
|
- (CocoaSecurityResult *)aesEncrypt:(NSString *)data hexKey:(NSString *)key hexIv:(NSString *)iv
|
|
{
|
|
CocoaSecurityDecoder *decoder = [CocoaSecurityDecoder new];
|
|
NSData *aesKey = [decoder hex:key];
|
|
NSData *aesIv = [decoder hex:iv];
|
|
|
|
return [self aesEncrypt:data key:aesKey iv:aesIv];
|
|
}
|
|
- (CocoaSecurityResult *)aesEncrypt:(NSString *)data key:(NSData *)key iv:(NSData *)iv
|
|
{
|
|
return [self aesEncryptWithData:[data dataUsingEncoding:NSUTF8StringEncoding] key:key iv:iv];
|
|
}
|
|
- (CocoaSecurityResult *)aesEncryptWithData:(NSData *)data key:(NSData *)key iv:(NSData *)iv
|
|
{
|
|
// check length of key and iv
|
|
if ([iv length] != 16) {
|
|
@throw [NSException exceptionWithName:@"Cocoa Security"
|
|
reason:@"Length of iv is wrong. Length of iv should be 16(128bits)"
|
|
userInfo:nil];
|
|
}
|
|
if ([key length] != 16 && [key length] != 24 && [key length] != 32 ) {
|
|
@throw [NSException exceptionWithName:@"Cocoa Security"
|
|
reason:@"Length of key is wrong. Length of iv should be 16, 24 or 32(128, 192 or 256bits)"
|
|
userInfo:nil];
|
|
}
|
|
|
|
// setup output buffer
|
|
size_t bufferSize = [data length] + kCCBlockSizeAES128;
|
|
void *buffer = malloc(bufferSize);
|
|
|
|
// do encrypt
|
|
size_t encryptedSize = 0;
|
|
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
|
|
kCCAlgorithmAES128,
|
|
kCCOptionPKCS7Padding,
|
|
[key bytes], // Key
|
|
[key length], // kCCKeySizeAES
|
|
[iv bytes], // IV
|
|
[data bytes],
|
|
[data length],
|
|
buffer,
|
|
bufferSize,
|
|
&encryptedSize);
|
|
if (cryptStatus == kCCSuccess) {
|
|
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:buffer length:encryptedSize];
|
|
free(buffer);
|
|
|
|
return result;
|
|
}
|
|
else {
|
|
free(buffer);
|
|
@throw [NSException exceptionWithName:@"Cocoa Security"
|
|
reason:@"Encrypt Error!"
|
|
userInfo:nil];
|
|
return nil;
|
|
}
|
|
}
|
|
#pragma mark - AES Decrypt
|
|
// default AES Decrypt, key -> SHA384(key).sub(0, 32), iv -> SHA384(key).sub(32, 16)
|
|
+ (CocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data key:(NSString *)key
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs aesDecryptWithBase64:data key:key];
|
|
}
|
|
- (CocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data key:(NSString *)key
|
|
{
|
|
CocoaSecurityResult * sha = [self sha384:key];
|
|
NSData *aesKey = [sha.data subdataWithRange:NSMakeRange(0, 32)];
|
|
NSData *aesIv = [sha.data subdataWithRange:NSMakeRange(32, 16)];
|
|
|
|
return [self aesDecryptWithBase64:data key:aesKey iv:aesIv];
|
|
}
|
|
#pragma mark AES Decrypt 128, 192, 256
|
|
+ (CocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data hexKey:(NSString *)key hexIv:(NSString *)iv
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs aesDecryptWithBase64:data hexKey:key hexIv:iv];
|
|
}
|
|
+ (CocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data key:(NSData *)key iv:(NSData *)iv
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs aesDecryptWithBase64:data key:key iv:iv];
|
|
}
|
|
+ (CocoaSecurityResult *)aesDecryptWithData:(NSData *)data key:(NSData *)key iv:(NSData *)iv
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs aesDecryptWithData:data key:key iv:iv];
|
|
}
|
|
- (CocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data hexKey:(NSString *)key hexIv:(NSString *)iv
|
|
{
|
|
CocoaSecurityDecoder *decoder = [CocoaSecurityDecoder new];
|
|
NSData *aesKey = [decoder hex:key];
|
|
NSData *aesIv = [decoder hex:iv];
|
|
|
|
return [self aesDecryptWithBase64:data key:aesKey iv:aesIv];
|
|
}
|
|
- (CocoaSecurityResult *)aesDecryptWithBase64:(NSString *)data key:(NSData *)key iv:(NSData *)iv
|
|
{
|
|
CocoaSecurityDecoder *decoder = [CocoaSecurityDecoder new];
|
|
return [self aesDecryptWithData:[decoder base64:data] key:key iv:iv];
|
|
}
|
|
- (CocoaSecurityResult *)aesDecryptWithData:(NSData *)data key:(NSData *)key iv:(NSData *)iv
|
|
{
|
|
// check length of key and iv
|
|
if ([iv length] != 16) {
|
|
@throw [NSException exceptionWithName:@"Cocoa Security"
|
|
reason:@"Length of iv is wrong. Length of iv should be 16(128bits)"
|
|
userInfo:nil];
|
|
}
|
|
if ([key length] != 16 && [key length] != 24 && [key length] != 32 ) {
|
|
@throw [NSException exceptionWithName:@"Cocoa Security"
|
|
reason:@"Length of key is wrong. Length of iv should be 16, 24 or 32(128, 192 or 256bits)"
|
|
userInfo:nil];
|
|
}
|
|
|
|
// setup output buffer
|
|
size_t bufferSize = [data length] + kCCBlockSizeAES128;
|
|
void *buffer = malloc(bufferSize);
|
|
|
|
// do encrypt
|
|
size_t encryptedSize = 0;
|
|
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
|
|
kCCAlgorithmAES128,
|
|
kCCOptionPKCS7Padding,
|
|
[key bytes], // Key
|
|
[key length], // kCCKeySizeAES
|
|
[iv bytes], // IV
|
|
[data bytes],
|
|
[data length],
|
|
buffer,
|
|
bufferSize,
|
|
&encryptedSize);
|
|
if (cryptStatus == kCCSuccess) {
|
|
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:buffer length:encryptedSize];
|
|
free(buffer);
|
|
|
|
return result;
|
|
}
|
|
else {
|
|
free(buffer);
|
|
@throw [NSException exceptionWithName:@"Cocoa Security"
|
|
reason:@"Decrypt Error!"
|
|
userInfo:nil];
|
|
return nil;
|
|
}
|
|
}
|
|
|
|
|
|
#pragma mark - MD5
|
|
+ (CocoaSecurityResult *)md5:(NSString *)hashString
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs md5:hashString];
|
|
}
|
|
+ (CocoaSecurityResult *)md5WithData:(NSData *)hashData
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs md5WithData:hashData];
|
|
}
|
|
- (CocoaSecurityResult *)md5:(NSString *)hashString
|
|
{
|
|
return [self md5WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding]];
|
|
}
|
|
- (CocoaSecurityResult *)md5WithData:(NSData *)hashData
|
|
{
|
|
unsigned char *digest;
|
|
digest = malloc(CC_MD5_DIGEST_LENGTH);
|
|
|
|
CC_MD5([hashData bytes], [hashData length], digest);
|
|
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_MD5_DIGEST_LENGTH];
|
|
free(digest);
|
|
|
|
return result;
|
|
}
|
|
#pragma mark - HMAC-MD5
|
|
+ (CocoaSecurityResult *)hmacMd5:(NSString *)hashString hmacKey:(NSString *)key
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs hmacMd5:hashString hmacKey:key];
|
|
}
|
|
+ (CocoaSecurityResult *)hmacMd5WithData:(NSData *)hashData hmacKey:(NSString *)key
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs hmacMd5WithData:hashData hmacKey:key];
|
|
}
|
|
- (CocoaSecurityResult *)hmacMd5:(NSString *)hashString hmacKey:(NSString *)key
|
|
{
|
|
return [self hmacMd5WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding] hmacKey:key];
|
|
}
|
|
- (CocoaSecurityResult *)hmacMd5WithData:(NSData *)hashData hmacKey:(NSString *)key
|
|
{
|
|
unsigned char *digest;
|
|
digest = malloc(CC_MD5_DIGEST_LENGTH);
|
|
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
CCHmac(kCCHmacAlgMD5, cKey, strlen(cKey), [hashData bytes], [hashData length], digest);
|
|
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_MD5_DIGEST_LENGTH];
|
|
free(digest);
|
|
cKey = nil;
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
#pragma mark - SHA1
|
|
+ (CocoaSecurityResult *)sha1:(NSString *)hashString
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs sha1:hashString];
|
|
}
|
|
+ (CocoaSecurityResult *)sha1WithData:(NSData *)hashData
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs sha1WithData:hashData];
|
|
}
|
|
- (CocoaSecurityResult *)sha1:(NSString *)hashString
|
|
{
|
|
return [self sha1WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding]];
|
|
}
|
|
- (CocoaSecurityResult *)sha1WithData:(NSData *)hashData
|
|
{
|
|
unsigned char *digest;
|
|
digest = malloc(CC_SHA1_DIGEST_LENGTH);
|
|
|
|
CC_SHA1([hashData bytes], [hashData length], digest);
|
|
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
|
|
free(digest);
|
|
|
|
return result;
|
|
}
|
|
#pragma mark SHA224
|
|
+ (CocoaSecurityResult *)sha224:(NSString *)hashString
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs sha224:hashString];
|
|
}
|
|
+ (CocoaSecurityResult *)sha224WithData:(NSData *)hashData
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs sha224WithData:hashData];
|
|
}
|
|
- (CocoaSecurityResult *)sha224:(NSString *)hashString
|
|
{
|
|
return [self sha224WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding]];
|
|
}
|
|
- (CocoaSecurityResult *)sha224WithData:(NSData *)hashData
|
|
{
|
|
unsigned char *digest;
|
|
digest = malloc(CC_SHA224_DIGEST_LENGTH);
|
|
|
|
CC_SHA224([hashData bytes], [hashData length], digest);
|
|
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA224_DIGEST_LENGTH];
|
|
free(digest);
|
|
|
|
return result;
|
|
}
|
|
#pragma mark SHA256
|
|
+ (CocoaSecurityResult *)sha256:(NSString *)hashString
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs sha256:hashString];
|
|
}
|
|
+ (CocoaSecurityResult *)sha256WithData:(NSData *)hashData
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs sha256WithData:hashData];
|
|
}
|
|
- (CocoaSecurityResult *)sha256:(NSString *)hashString
|
|
{
|
|
return [self sha256WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding]];
|
|
}
|
|
- (CocoaSecurityResult *)sha256WithData:(NSData *)hashData
|
|
{
|
|
unsigned char *digest;
|
|
digest = malloc(CC_SHA256_DIGEST_LENGTH);
|
|
|
|
CC_SHA256([hashData bytes], [hashData length], digest);
|
|
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA256_DIGEST_LENGTH];
|
|
free(digest);
|
|
|
|
return result;
|
|
}
|
|
#pragma mark SHA384
|
|
+ (CocoaSecurityResult *)sha384:(NSString *)hashString
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs sha384:hashString];
|
|
}
|
|
+ (CocoaSecurityResult *)sha384WithData:(NSData *)hashData
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs sha384WithData:hashData];
|
|
}
|
|
- (CocoaSecurityResult *)sha384:(NSString *)hashString
|
|
{
|
|
return [self sha384WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding]];
|
|
}
|
|
- (CocoaSecurityResult *)sha384WithData:(NSData *)hashData
|
|
{
|
|
unsigned char *digest;
|
|
digest = malloc(CC_SHA384_DIGEST_LENGTH);
|
|
|
|
CC_SHA384([hashData bytes], [hashData length], digest);
|
|
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA384_DIGEST_LENGTH];
|
|
free(digest);
|
|
|
|
return result;
|
|
}
|
|
#pragma mark SHA512
|
|
+ (CocoaSecurityResult *)sha512:(NSString *)hashString
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs sha512:hashString];
|
|
}
|
|
+ (CocoaSecurityResult *)sha512WithData:(NSData *)hashData
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs sha512WithData:hashData];
|
|
}
|
|
- (CocoaSecurityResult *)sha512:(NSString *)hashString
|
|
{
|
|
return [self sha512WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding]];
|
|
}
|
|
- (CocoaSecurityResult *)sha512WithData:(NSData *)hashData
|
|
{
|
|
unsigned char *digest;
|
|
digest = malloc(CC_SHA512_DIGEST_LENGTH);
|
|
|
|
CC_SHA512([hashData bytes], [hashData length], digest);
|
|
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA512_DIGEST_LENGTH];
|
|
free(digest);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
#pragma mark - HMAC-SHA1
|
|
+ (CocoaSecurityResult *)hmacSha1:(NSString *)hashString hmacKey:(NSString *)key
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs hmacSha1:hashString hmacKey:key];
|
|
}
|
|
+ (CocoaSecurityResult *)hmacSha1WithData:(NSData *)hashData hmacKey:(NSString *)key
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs hmacSha1WithData:hashData hmacKey:key];
|
|
}
|
|
- (CocoaSecurityResult *)hmacSha1:(NSString *)hashString hmacKey:(NSString *)key
|
|
{
|
|
return [self hmacSha1WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding] hmacKey:key];
|
|
}
|
|
- (CocoaSecurityResult *)hmacSha1WithData:(NSData *)hashData hmacKey:(NSString *)key
|
|
{
|
|
unsigned char *digest;
|
|
digest = malloc(CC_SHA1_DIGEST_LENGTH);
|
|
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), [hashData bytes], [hashData length], digest);
|
|
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
|
|
free(digest);
|
|
cKey = nil;
|
|
|
|
return result;
|
|
}
|
|
#pragma mark HMAC-SHA224
|
|
+ (CocoaSecurityResult *)hmacSha224:(NSString *)hashString hmacKey:(NSString *)key
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs hmacSha224:hashString hmacKey:key];
|
|
}
|
|
+ (CocoaSecurityResult *)hmacSha224WithData:(NSData *)hashData hmacKey:(NSString *)key
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs hmacSha224WithData:hashData hmacKey:key];
|
|
}
|
|
- (CocoaSecurityResult *)hmacSha224:(NSString *)hashString hmacKey:(NSString *)key
|
|
{
|
|
return [self hmacSha224WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding] hmacKey:key];
|
|
}
|
|
- (CocoaSecurityResult *)hmacSha224WithData:(NSData *)hashData hmacKey:(NSString *)key
|
|
{
|
|
unsigned char *digest;
|
|
digest = malloc(CC_SHA224_DIGEST_LENGTH);
|
|
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
CCHmac(kCCHmacAlgSHA224, cKey, strlen(cKey), [hashData bytes], [hashData length], digest);
|
|
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA224_DIGEST_LENGTH];
|
|
free(digest);
|
|
cKey = nil;
|
|
|
|
return result;
|
|
}
|
|
#pragma mark HMAC-SHA256
|
|
+ (CocoaSecurityResult *)hmacSha256:(NSString *)hashString hmacKey:(NSString *)key
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs hmacSha256:hashString hmacKey:key];
|
|
}
|
|
+ (CocoaSecurityResult *)hmacSha256WithData:(NSData *)hashData hmacKey:(NSString *)key
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs hmacSha256WithData:hashData hmacKey:key];
|
|
}
|
|
- (CocoaSecurityResult *)hmacSha256:(NSString *)hashString hmacKey:(NSString *)key
|
|
{
|
|
return [self hmacSha256WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding] hmacKey:key];
|
|
}
|
|
- (CocoaSecurityResult *)hmacSha256WithData:(NSData *)hashData hmacKey:(NSString *)key
|
|
{
|
|
unsigned char *digest;
|
|
digest = malloc(CC_SHA256_DIGEST_LENGTH);
|
|
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), [hashData bytes], [hashData length], digest);
|
|
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA256_DIGEST_LENGTH];
|
|
free(digest);
|
|
cKey = nil;
|
|
|
|
return result;
|
|
}
|
|
#pragma mark HMAC-SHA384
|
|
+ (CocoaSecurityResult *)hmacSha384:(NSString *)hashString hmacKey:(NSString *)key
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs hmacSha384:hashString hmacKey:key];
|
|
}
|
|
+ (CocoaSecurityResult *)hmacSha384WithData:(NSData *)hashData hmacKey:(NSString *)key
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs hmacSha384WithData:hashData hmacKey:key];
|
|
}
|
|
- (CocoaSecurityResult *)hmacSha384:(NSString *)hashString hmacKey:(NSString *)key
|
|
{
|
|
return [self hmacSha384WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding] hmacKey:key];
|
|
}
|
|
- (CocoaSecurityResult *)hmacSha384WithData:(NSData *)hashData hmacKey:(NSString *)key
|
|
{
|
|
unsigned char *digest;
|
|
digest = malloc(CC_SHA384_DIGEST_LENGTH);
|
|
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
CCHmac(kCCHmacAlgSHA384, cKey, strlen(cKey), [hashData bytes], [hashData length], digest);
|
|
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA384_DIGEST_LENGTH];
|
|
free(digest);
|
|
cKey = nil;
|
|
|
|
return result;
|
|
}
|
|
#pragma mark HMAC-SHA512
|
|
+ (CocoaSecurityResult *)hmacSha512:(NSString *)hashString hmacKey:(NSString *)key
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs hmacSha512:hashString hmacKey:key];
|
|
}
|
|
+ (CocoaSecurityResult *)hmacSha512WithData:(NSData *)hashData hmacKey:(NSString *)key
|
|
{
|
|
CocoaSecurity *cs = [CocoaSecurity new];
|
|
return [cs hmacSha512WithData:hashData hmacKey:key];
|
|
}
|
|
- (CocoaSecurityResult *)hmacSha512:(NSString *)hashString hmacKey:(NSString *)key
|
|
{
|
|
return [self hmacSha512WithData:[hashString dataUsingEncoding:NSUTF8StringEncoding] hmacKey:key];
|
|
}
|
|
- (CocoaSecurityResult *)hmacSha512WithData:(NSData *)hashData hmacKey:(NSString *)key
|
|
{
|
|
unsigned char *digest;
|
|
digest = malloc(CC_SHA512_DIGEST_LENGTH);
|
|
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
CCHmac(kCCHmacAlgSHA512, cKey, strlen(cKey), [hashData bytes], [hashData length], digest);
|
|
CocoaSecurityResult *result = [[CocoaSecurityResult alloc] initWithBytes:digest length:CC_SHA512_DIGEST_LENGTH];
|
|
free(digest);
|
|
cKey = nil;
|
|
|
|
return result;
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
#pragma mark - CocoaSecurityResult
|
|
@implementation CocoaSecurityResult
|
|
|
|
@synthesize data = _data;
|
|
|
|
#pragma mark - Init
|
|
- (id)initWithBytes:(unsigned char[])initData length:(NSUInteger)length
|
|
{
|
|
self = [super init];
|
|
if (self) {
|
|
_data = [NSData dataWithBytes:initData length:length];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
#pragma mark UTF8 String
|
|
// convert CocoaSecurityResult to UTF8 string
|
|
- (NSString *)utf8String
|
|
{
|
|
NSString *result = [[NSString alloc] initWithData:_data encoding:NSUTF8StringEncoding];
|
|
return result;
|
|
}
|
|
|
|
#pragma mark HEX
|
|
// convert CocoaSecurityResult to HEX string
|
|
- (NSString *)hex
|
|
{
|
|
CocoaSecurityEncoder *encoder = [CocoaSecurityEncoder new];
|
|
return [encoder hex:_data useLower:false];
|
|
}
|
|
- (NSString *)hexLower
|
|
{
|
|
CocoaSecurityEncoder *encoder = [CocoaSecurityEncoder new];
|
|
return [encoder hex:_data useLower:true];
|
|
}
|
|
|
|
#pragma mark Base64
|
|
// convert CocoaSecurityResult to Base64 string
|
|
- (NSString *)base64
|
|
{
|
|
CocoaSecurityEncoder *encoder = [CocoaSecurityEncoder new];
|
|
return [encoder base64:_data];
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
#pragma mark - CocoaSecurityEncoder
|
|
@implementation CocoaSecurityEncoder
|
|
|
|
// convert NSData to Base64
|
|
- (NSString *)base64:(NSData *)data
|
|
{
|
|
static const char lookup[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
|
|
long long inputLength = [data length];
|
|
const unsigned char *inputBytes = [data bytes];
|
|
|
|
long long maxOutputLength = (inputLength / 3 + 1) * 4;
|
|
unsigned char *outputBytes = (unsigned char *)malloc(maxOutputLength);
|
|
|
|
long long index;
|
|
long long outputLength = 0;
|
|
for (index = 0; index < inputLength - 2; index += 3)
|
|
{
|
|
outputBytes[outputLength++] = lookup[(inputBytes[index] & 0xFC) >> 2];
|
|
outputBytes[outputLength++] = lookup[((inputBytes[index] & 0x03) << 4) | ((inputBytes[index + 1] & 0xF0) >> 4)];
|
|
outputBytes[outputLength++] = lookup[((inputBytes[index + 1] & 0x0F) << 2) | ((inputBytes[index + 2] & 0xC0) >> 6)];
|
|
outputBytes[outputLength++] = lookup[inputBytes[index + 2] & 0x3F];
|
|
}
|
|
|
|
//handle left-over data
|
|
if (index == inputLength - 2)
|
|
{
|
|
// = terminator
|
|
outputBytes[outputLength++] = lookup[(inputBytes[index] & 0xFC) >> 2];
|
|
outputBytes[outputLength++] = lookup[((inputBytes[index] & 0x03) << 4) | ((inputBytes[index + 1] & 0xF0) >> 4)];
|
|
outputBytes[outputLength++] = lookup[(inputBytes[index + 1] & 0x0F) << 2];
|
|
outputBytes[outputLength++] = '=';
|
|
}
|
|
else if (index == inputLength - 1)
|
|
{
|
|
// == terminator
|
|
outputBytes[outputLength++] = lookup[(inputBytes[index] & 0xFC) >> 2];
|
|
outputBytes[outputLength++] = lookup[(inputBytes[index] & 0x03) << 4];
|
|
outputBytes[outputLength++] = '=';
|
|
outputBytes[outputLength++] = '=';
|
|
}
|
|
|
|
NSString *result;
|
|
if (outputLength >= 4)
|
|
{
|
|
//truncate data to match actual output length
|
|
outputBytes = realloc(outputBytes, outputLength);
|
|
result = [[NSString alloc] initWithBytes:outputBytes length:outputLength encoding:NSASCIIStringEncoding];
|
|
}
|
|
free(outputBytes);
|
|
return result;
|
|
}
|
|
|
|
// convert NSData to hex string
|
|
- (NSString *)hex:(NSData *)data useLower:(BOOL)isOutputLower
|
|
{
|
|
if (data.length == 0) { return nil; }
|
|
|
|
static const char HexEncodeCharsLower[] = "0123456789abcdef";
|
|
static const char HexEncodeChars[] = "0123456789ABCDEF";
|
|
char *resultData;
|
|
// malloc result data
|
|
resultData = malloc([data length] * 2 +1);
|
|
// convert imgData(NSData) to char[]
|
|
unsigned char *sourceData = ((unsigned char *)[data bytes]);
|
|
NSUInteger length = [data length];
|
|
|
|
if (isOutputLower) {
|
|
for (NSUInteger index = 0; index < length; index++) {
|
|
// set result data
|
|
resultData[index * 2] = HexEncodeCharsLower[(sourceData[index] >> 4)];
|
|
resultData[index * 2 + 1] = HexEncodeCharsLower[(sourceData[index] % 0x10)];
|
|
}
|
|
}
|
|
else {
|
|
for (NSUInteger index = 0; index < length; index++) {
|
|
// set result data
|
|
resultData[index * 2] = HexEncodeChars[(sourceData[index] >> 4)];
|
|
resultData[index * 2 + 1] = HexEncodeChars[(sourceData[index] % 0x10)];
|
|
}
|
|
}
|
|
resultData[[data length] * 2] = 0;
|
|
|
|
// convert result(char[]) to NSString
|
|
NSString *result = [NSString stringWithCString:resultData encoding:NSASCIIStringEncoding];
|
|
sourceData = nil;
|
|
free(resultData);
|
|
|
|
return result;
|
|
}
|
|
|
|
@end
|
|
|
|
#pragma mark - CocoaSecurityDecoder
|
|
@implementation CocoaSecurityDecoder
|
|
- (NSData *)base64:(NSString *)string
|
|
{
|
|
static const char lookup[] =
|
|
{
|
|
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
|
|
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
|
|
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 62, 99, 99, 99, 63,
|
|
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 99, 99, 99, 99, 99, 99,
|
|
99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 99, 99, 99, 99, 99,
|
|
99, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
|
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 99, 99, 99, 99, 99
|
|
};
|
|
|
|
NSData *inputData = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
|
|
NSUInteger inputLength = [inputData length];
|
|
const unsigned char *inputBytes = [inputData bytes];
|
|
|
|
NSMutableData *outputData = [NSMutableData dataWithLength:(inputLength / 4 + 1) * 3];
|
|
unsigned char *outputBytes = (unsigned char *)[outputData mutableBytes];
|
|
|
|
int accumulator = 0;
|
|
long long outputLength = 0;
|
|
unsigned char accumulated[] = {0, 0, 0, 0};
|
|
for (NSUInteger index = 0; index < inputLength; index++)
|
|
{
|
|
unsigned char decoded = lookup[inputBytes[index] & 0x7F];
|
|
if (decoded != 99)
|
|
{
|
|
accumulated[accumulator] = decoded;
|
|
if (accumulator == 3)
|
|
{
|
|
outputBytes[outputLength++] = (accumulated[0] << 2) | (accumulated[1] >> 4);
|
|
outputBytes[outputLength++] = (accumulated[1] << 4) | (accumulated[2] >> 2);
|
|
outputBytes[outputLength++] = (accumulated[2] << 6) | accumulated[3];
|
|
}
|
|
accumulator = (accumulator + 1) % 4;
|
|
}
|
|
}
|
|
|
|
//handle left-over data
|
|
if (accumulator > 0) outputBytes[outputLength] = (accumulated[0] << 2) | (accumulated[1] >> 4);
|
|
if (accumulator > 1) outputBytes[++outputLength] = (accumulated[1] << 4) | (accumulated[2] >> 2);
|
|
if (accumulator > 2) outputLength++;
|
|
|
|
//truncate data to match actual output length
|
|
outputData.length = outputLength;
|
|
return outputLength? outputData: nil;
|
|
}
|
|
- (NSData *)hex:(NSString *)data
|
|
{
|
|
if (data.length == 0) { return nil; }
|
|
|
|
static const unsigned char HexDecodeChars[] =
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, //49
|
|
2, 3, 4, 5, 6, 7, 8, 9, 0, 0, //59
|
|
0, 0, 0, 0, 0, 10, 11, 12, 13, 14,
|
|
15, 0, 0, 0, 0, 0, 0, 0, 0, 0, //79
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 10, 11, 12, //99
|
|
13, 14, 15
|
|
};
|
|
|
|
// convert data(NSString) to CString
|
|
const char *source = [data cStringUsingEncoding:NSUTF8StringEncoding];
|
|
// malloc buffer
|
|
unsigned char *buffer;
|
|
NSUInteger length = strlen(source) / 2;
|
|
buffer = malloc(length);
|
|
for (NSUInteger index = 0; index < length; index++) {
|
|
buffer[index] = (HexDecodeChars[source[index * 2]] << 4) + (HexDecodeChars[source[index * 2 + 1]]);
|
|
}
|
|
// init result NSData
|
|
NSData *result = [NSData dataWithBytes:buffer length:length];
|
|
free(buffer);
|
|
source = nil;
|
|
|
|
return result;
|
|
}
|
|
|
|
@end
|