Wednesday, 30 May 2018

AES 256 Encryption and Decryption in iOS, OPENSSL

Required things for AES 256 Encryption and Decryption


  • Key Should be 64Characters of base64 for 256 AES Encryption
  • IV Should be 32Characters of base64 for 256 AES Encryption
  • for example key = "3034F6E32958647FDFF75D265B455EBF40C80E6D597092B3A802B3E5863F878E
  • and iv = "00000000000000000000000000000000"
  • key and iv can be any charaters with base64 characters like 0 to 9 and ABCDEF


openssl Requires help key words for AES Encryption and Decryption

usage: enc -ciphername [-AadePp] [-base64] [-bufsize number] [-debug]
    [-engine id] [-in file] [-iv IV] [-K key] [-k password]
    [-kfile file] [-md digest] [-none] [-nopad] [-nosalt]
    [-out file] [-pass arg] [-S salt] [-salt]

 -A                 Process base64 data on one line (requires -a)
 -a                 Perform base64 encoding/decoding (alias -base64)
 -bufsize size      Specify the buffer size to use for I/O
 -d                 Decrypt the input data
 -debug             Print debugging information
 -e                 Encrypt the input data (default)
 -engine id         Use the engine specified by the given identifier
 -in file           Input file to read from (default stdin)
 -iv IV             IV to use, specified as a hexidecimal string
 -K key             Key to use, specified as a hexidecimal string
 -md digest         Digest to use to create a key from the passphrase
 -none              Use NULL cipher (no encryption or decryption)
 -nopad             Disable standard block padding
 -out file          Output file to write to (default stdout)
 -P                 Print out the salt, key and IV used, then exit
                      (no encryption or decryption is performed)
 -p                 Print out the salt, key and IV used
 -pass source       Password source
 -S salt            Salt to use, specified as a hexidecimal string
 -salt              Use a salt in the key derivation routines (default)
 -v                 Verbose

Valid ciphername values:

 -aes-128-cbc              -aes-128-cfb              -aes-128-cfb1            
 -aes-128-cfb8             -aes-128-ctr              -aes-128-ecb             
 -aes-128-gcm              -aes-128-ofb              -aes-128-xts             
 -aes-192-cbc              -aes-192-cfb              -aes-192-cfb1            
 -aes-192-cfb8             -aes-192-ctr              -aes-192-ecb             
 -aes-192-gcm              -aes-192-ofb              -aes-256-cbc             
 -aes-256-cfb              -aes-256-cfb1             -aes-256-cfb8            
 -aes-256-ctr              -aes-256-ecb              -aes-256-gcm             
 -aes-256-ofb              -aes-256-xts              -aes128                  
 -aes192                   -aes256                   -bf                      
 -bf-cbc                   -bf-cfb                   -bf-ecb                  
 -bf-ofb                   -blowfish                 -camellia-128-cbc        
 -camellia-128-cfb         -camellia-128-cfb1        -camellia-128-cfb8       
 -camellia-128-ecb         -camellia-128-ofb         -camellia-192-cbc        
 -camellia-192-cfb         -camellia-192-cfb1        -camellia-192-cfb8       
 -camellia-192-ecb         -camellia-192-ofb         -camellia-256-cbc        
 -camellia-256-cfb         -camellia-256-cfb1        -camellia-256-cfb8       
 -camellia-256-ecb         -camellia-256-ofb         -camellia128             
 -camellia192              -camellia256              -cast                    
 -cast-cbc                 -cast5-cbc                -cast5-cfb               
 -cast5-ecb                -cast5-ofb                -chacha                  
 -des                      -des-cbc                  -des-cfb                 
 -des-cfb1                 -des-cfb8                 -des-ecb                 
 -des-ede                  -des-ede-cbc              -des-ede-cfb             
 -des-ede-ofb              -des-ede3                 -des-ede3-cbc            
 -des-ede3-cfb             -des-ede3-cfb1            -des-ede3-cfb8           
 -des-ede3-ofb             -des-ofb                  -des3                    
 -desx                     -desx-cbc                 -gost89                  
 -gost89-cnt               -gost89-ecb               -id-aes128-GCM           
 -id-aes192-GCM            -id-aes256-GCM            -rc2                     
 -rc2-40-cbc               -rc2-64-cbc               -rc2-cbc                 
 -rc2-cfb                  -rc2-ecb                  -rc2-ofb                 
 -rc4                      -rc4-40                   -rc4-hmac-md5 







AES 256 Encryption and Decryption in OPENSSL in Command Prompt/Terminal

Create File name "testPlainText.enc" write any text required for example "My Name is Vishnu"



Encryption:

Write the below Command in terminal 

openssl enc -aes256 -A -a -p -K 3034F6E32958647FDFF75D265B455EBF40C80E6D597092B3A802B3E5863F878E -iv 00000000000000000000000000000000 -nosalt -in testPlainText.enc -out testEncBas64.enc

The out put will be like shown in below screen shots

1) Terminal Screen Shots

2) below screen shot is "testEncBas64.enc"

The "testEncBas64.enc" file contains encrypted base64 code. Now Decrypt this in terminal itself 
Please follow below command and screenshots of terminal

openssl enc -aes256 -A -p -K 3034F6E32958647FDFF75D265B455EBF40C80E6D597092B3A802B3E5863F878E -iv 00000000000000000000000000000000 -nosalt -base64 -d -in testEncBas64.enc














AES 256 Encryption and Decryption in OPENSSL in iOS Objective C

create files with name "aes.h" & "aes.m" and testViewController.htestViewController.h

aes.h


#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>

@interface NSData (AES)

- (NSData *)encryptedDataWithHexKey:(NSString*)hexKey hexIV:(NSString *)hexIV;
- (NSData *)decryptDataWithHexKey:(NSString*)hexKey hexIV:(NSString *)hexIV;

@end


aes.m


#import "aes.h"

@implementation NSData (AES)

+ (NSData *)dataFromHexString:(NSString *)string
{
    string = string.lowercaseString;
    NSMutableData *data = [[NSMutableData alloc] initWithCapacity:string.length/2];
    unsigned char whole_byte;
    char byte_chars[3] = {'\0','\0','\0'};
    int i = 0;
    NSUInteger length = string.length;
    while (i < length-1) {
        char c = [string characterAtIndex:i++];
        if (c < '0' || (c > '9' && c < 'a') || c > 'f')
            continue;
        byte_chars[0] = c;
        byte_chars[1] = [string characterAtIndex:i++];
        whole_byte = strtol(byte_chars, NULL, 16);
        [data appendBytes:&whole_byte length:1];
    }
    return data;
}

+ (void)fillDataArray:(char **)dataPtr length:(NSUInteger)length usingHexString:(NSString *)hexString
{
    NSData *data = [NSData dataFromHexString:hexString];
    NSAssert((data.length + 1) == length, @"The hex provided didn't decode to match length");
    
    unsigned long total_bytes = (length + 1) * sizeof(char);
    
    *dataPtr = malloc(total_bytes);
    bzero(*dataPtr, total_bytes);
    NSLog(@"total_bytes : %lu",total_bytes);
    memcpy(*dataPtr, data.bytes, data.length);
    NSLog(@"data.length : %lu",data.length);
}

- (NSData *)encryptedDataWithHexKey:(NSString*)hexKey hexIV:(NSString *)hexIV
{
    // Fetch key data and put into C string array padded with \0
    char *keyPtr;
    [NSData fillDataArray:&keyPtr length:kCCKeySizeAES256+1 usingHexString:hexKey];
    
    // Fetch iv data and put into C string array padded with \0
    char *ivPtr;
    [NSData fillDataArray:&ivPtr length:kCCKeySizeAES128+1 usingHexString:hexIV];
    
    // For block ciphers, the output size will always be less than or equal to the input size plus the size of one block because we add padding.
    // That's why we need to add the size of one block here
    NSUInteger dataLength = self.length;
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc( bufferSize );
    
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES256,
                                          ivPtr /* initialization vector */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesEncrypted);
    
    
    free(keyPtr);
    free(ivPtr);
    
    if(cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }
    
    free(buffer);
    return nil;
}

- (NSData *)decryptDataWithHexKey:(NSString*)hexKey hexIV:(NSString *)hexIV
{
    // Fetch key data and put into C string array padded with \0
    char *keyPtr;
    [NSData fillDataArray:&keyPtr length:kCCKeySizeAES256+1 usingHexString:hexKey];
    
    // Fetch iv data and put into C string array padded with \0
    char *ivPtr;
    [NSData fillDataArray:&ivPtr length:kCCKeySizeAES128+1 usingHexString:hexIV];
    
    // For block ciphers, the output size will always be less than or equal to the input size plus the size of one block because we add padding.
    // That's why we need to add the size of one block here
    NSUInteger dataLength = self.length;
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc( bufferSize );
    
    size_t numBytesDecrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt( kCCDecrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES256,
                                          ivPtr,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesDecrypted );
    free(keyPtr);
    free(ivPtr);
    
    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);
    return nil;
}
@end


testViewController.h


#import "aes.h"
#import <UIKit/UIKit.h>


@interface testViewController : UIViewController
@end


testViewController.m


- (Void)testFunction {
    /*hexKey Should be 64Characters of base64 for 256 AES Encryption*/
    NSString *hexKey = @"3034F6E32958647FDFF75D265B455EBF40C80E6D597092B3A802B3E5863F878E";
    NSString *hexIV = nil;
    /*hexIV Should be 32Characters of base64 for 256 AES Encryption*/
    hexIV = @"00000000000000000000000000000000";
    NSString *cipherText = nil;
    
    
    /* AES 256 Encryption*/
    NSString *encryptText = @"Testing123_Test123_End";
    NSData *data = [encryptText dataUsingEncoding:NSUTF8StringEncoding];
    NSData *encryptedPayload = [data encryptedDataWithHexKey:hexKey
                                                       hexIV:hexIV];
    if (encryptedPayload) {
        cipherText = [encryptedPayload base64EncodedStringWithOptions:0];
        NSLog(@"Encryped Result: %@", cipherText);
    }
    
    /* AES 256 Decryption*/
    if(cipherText){
        NSData *data = [[NSData alloc] initWithBase64EncodedString:cipherText options:0];
        NSAssert(data != nil, @"Couldn't base64 decode cipher text");
        
        NSData *decryptedPayload = [data decryptDataWithHexKey:hexKey
                                                         hexIV:hexIV];
        if (decryptedPayload) {
            NSString *decryptText = [[NSString alloc] initWithData:decryptedPayload encoding:NSUTF8StringEncoding];
            NSLog(@"Decrypted Result: %@", decryptText);
        }
    }
}









Any doubts: vishnu.lucky1991@gmail.com






























No comments:

Setting Up Multiple App Targets in Xcode from a Single Codebase

 To create two different apps (like "Light" and "Regular") from the same codebase in Xcode, you can follow these steps b...