iOS AES 加密(Java AES/CBC/PKCS5Pad

2020-11-07  本文已影响0人  iPhone
  1. kCCOptionPKCS7Padding | kCCOptionECBMode, iOS 默认是CBC
  2. java AES/CBC/PKCS5Padding , kCCOptionPKCS7Padding 兼容 PKCS5Padding
  3. https://github.com/qq20539350/AES.git
//
//  NSString+AES.m
//  jiajiemiTest
//
//  Created by lwf on 2020/11/7.
//  Copyright © 2020 10.12. All rights reserved.
//

#import "NSString+AES.h"
#import <CommonCrypto/CommonCrypto.h>
#import <CommonCrypto/CommonDigest.h>


static NSString * const VECTOR_KEY = @"b727aab332a752b1";
static NSString * const SECRET_KEY = @"f18749e18071a13b";

@implementation NSString (AES)

#pragma mark - Public
+ (NSString *)getSecretKey {
    NSString *uuid = [self getRandom_16];
    NSString *key = [self AES128_EncryptWithMessage:uuid key:SECRET_KEY];
    return key;
}

+ (NSString *)decryptSecretKey:(NSString *)secretKey {
    NSString * key = [self AES128_DecryptWithMessage:secretKey key:SECRET_KEY];
    return key;
}

+ (NSString *)AES128_EncryptWithMessage:(NSString *)message key:(NSString *)key {
    NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding];
    NSData * encryData = [self AES128_Encrypt:key encryptData:data giv:VECTOR_KEY];
//    NSString *output = [encryData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    NSString *output = [self hexStringWithData:encryData];
    return output;
}

+ (NSString *)AES128_DecryptWithMessage:(NSString *)message key:(NSString *)key{
//    NSData *data = [[NSData alloc] initWithBase64EncodedString:message options:NSDataBase64DecodingIgnoreUnknownCharacters];
    NSData *data = [NSString dataWithHexString:message];
    NSData * encryptData =  [self AES128_Decrypt:key encryptData:data giv:VECTOR_KEY];
    NSString *output = [[NSString alloc] initWithData:encryptData encoding:NSUTF8StringEncoding];
//    NSString *test = [NSString dataWithHexString:encryptData];
    return output;
}

#pragma mark - Private

+ (NSString *)getRandom_16 {
    NSString * uuidStr =  [[[NSUUID UUID] UUIDString] stringByReplacingOccurrencesOfString:@"-" withString:@""];
    NSString * random = [uuidStr substringWithRange:NSMakeRange(8, 16)];
    return  random;
}

#pragma mark - AES加密
// kCCOptionPKCS7Padding | kCCOptionECBMode, iOS 默认是CBC
// java AES/CBC/PKCS5Padding , kCCOptionPKCS7Padding 兼容 PKCS5Padding
+ (NSData *)AES128_Encrypt:(NSString *)key encryptData:(NSData *)data giv:(NSString *)gIv{

    char keyPtr[kCCKeySizeAES128+1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    char ivPtr[kCCKeySizeAES128+1];
    bzero(ivPtr, sizeof(ivPtr));
    [gIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          ivPtr,
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytes:buffer length:numBytesEncrypted];
    }
    free(buffer);
    return nil;
}

//大端与小端互转
+ (NSData *)dataTransfromBigOrSmall:(NSData *)data
{
    NSString *tmpStr = [self dataChangeToString:data];
    NSMutableArray *tmpArra = [NSMutableArray array];
    for (int i = 0 ;i<data.length*2 ;i+=2)
 {
        NSString *str = [tmpStr substringWithRange:NSMakeRange(i, 2)];
        [tmpArra addObject:str];
    }
    NSArray *lastArray = [[tmpArra reverseObjectEnumerator] allObjects];
    NSMutableString *lastStr = [NSMutableString string];
    for (NSString *str in lastArray)
 {
        [lastStr appendString:str];
    }
    NSData *lastData = [self HexStringToData:lastStr];
    return lastData;
}

+ (NSString*)dataChangeToString:(NSData*)data
{
    NSString * string = [NSString stringWithFormat:@"%@",data];
    string = [string stringByReplacingOccurrencesOfString:@"<" withString:@""];
    string = [string stringByReplacingOccurrencesOfString:@">" withString:@""];
    string = [string stringByReplacingOccurrencesOfString:@" " withString:@""];
    return string;
}

+ (NSMutableData*)HexStringToData:(NSString*)str
{
    NSString *command = str;
    command = [command stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSMutableData *commandToSend= [[NSMutableData alloc] init];
    unsigned char whole_byte;
    char byte_chars[3] = {'\0','\0','\0'};
    int i;
    for (i=0; i < [command length]/2; i++) {
        byte_chars[0] = [command characterAtIndex:i*2];
        byte_chars[1] = [command characterAtIndex:i*2+1];
        whole_byte = strtol(byte_chars, NULL, 16);
        [commandToSend appendBytes:&whole_byte length:1];
    }
    return commandToSend;
}
    
+ (NSData *)dataWithHexString:(NSString *)hexString {
    const char *chars = [hexString UTF8String];
    int i = 0;
    NSUInteger len = hexString.length;

    NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
    char byteChars[3] = {'\0','\0','\0'};
    unsigned long wholeByte;

    while (i < len) {
        byteChars[0] = chars[i++];
        byteChars[1] = chars[i++];
        wholeByte = strtoul(byteChars, NULL, 16);
        [data appendBytes:&wholeByte length:1];
    }

    return data;
}

+ (NSString *)hexStringWithData:(NSData *)data {
    const unsigned char *dataBuffer = (const unsigned char *)[data bytes];
    if (!dataBuffer) {
        return [NSString string];
    }

    NSUInteger          dataLength  = [data length];
    NSMutableString     *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];

    for (int i = 0; i < dataLength; ++i) {
        [hexString appendFormat:@"%02x", (unsigned char)dataBuffer[i]];
    }
    return [NSString stringWithString:hexString];
}


//AES128解密data(带自定义向量)
// kCCOptionECBMode
+ (NSData *)AES128_Decrypt:(NSString *)key encryptData:(NSData *)data giv:(NSString *)gIv{
    char keyPtr[kCCKeySizeAES128+1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    char ivPtr[kCCKeySizeAES128+1];
    bzero(ivPtr, sizeof(ivPtr));
    [gIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
    
    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesDecrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          ivPtr,
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesDecrypted);
    
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    }
    free(buffer);
    return nil;
}

@end

上一篇下一篇

猜你喜欢

热点阅读