decrypt value from blowfish in Objective-C code - ios

I am recieving the Encrypted data by server (BLOWFISH ALGORITHM) , I have to decrypt it by using blowfish algorithm in IOS.
you can donwload my code from here : https://www.dropbox.com/s/nswsm7des7isgd5/BlowfishTest-4.zip
I am struggling from 2 days with this task , I try lot of links and find few useful :
Blowfish Source code
How to implement Blowfish algorithm in iOS
http://www.codeding.com/articles/blowfish-encryption-algorithm-for-iphone
In third link, i got ECB ( I have to decrypt using ECB). but this code also not gives correct output after decryption.
I am using a online tool for testing and this shows correct output : http://www.tools4noobs.com/online_tools/decrypt/
Key = 20zE1E47BE57$51
Input value is = aed5c110d793f850521a4dd3a56a70d9
Algorithm = BLOWFISH
Mode = ECB
Decode the input using= Hexa
output = aYzY1380188405 ( this is correct output which i want)
and I am getting : ¹àÀhÒ¢º¹iÂF
Here is my code :
//Mode selected by default in nib: “ECB”
NSString *modeString = [encryptionModeControl titleForSegmentAtIndex:encryptionModeControl.selectedSegmentIndex];
BlowfishAlgorithm *blowFish = [BlowfishAlgorithm new];
[blowFish setMode:[BlowfishAlgorithm buildModeEnum:modeString]];
[blowFish setKey:key];
[blowFish setInitVector:initVector];
[blowFish setupKey];
NSString *cipherText = cipherTextView.text;
NSString *plainText = [blowFish decrypt:cipherText];
NSLog(#"cipher-text: %#", cipherText);
NSLog(#"plain-text: %#", plainText);
Note : Server side data is Encrypted using BLOWFISH in ECB mode, and converted to hexadecimal notation.

1) Source of Blowfish routines from David Madore: ftp://quatramaran.ens.fr/pub/madore/misc/blowfish.c
Pls note that in this source .h part should be separated from the .c file.
2) To use Pandora API we have to use the passwords given by its wiki page here:
http://pan-do-ra-api.wikia.com/wiki/Json/5/partners
Currently decrypt password is: 20zE1E47BE57$51
3) Use this code snippet (standing on great programmers' shoulders) - original Pandora API implementation is here: https://github.com/alexcrichton/hermes
In AppDelegate.h (for simplicity)
#define PARTNER_DECRYPT "20zE1E47BE57$51"
...
-(NSData*) PandoraDecrypt:(NSString*) string;
In AppDelegate.m
static char h2i[256] = {
['0'] = 0, ['1'] = 1, ['2'] = 2, ['3'] = 3, ['4'] = 4, ['5'] = 5, ['6'] = 6,
['7'] = 7, ['8'] = 8, ['9'] = 9, ['a'] = 10, ['b'] = 11, ['c'] = 12,
['d'] = 13, ['e'] = 14, ['f'] = 15
};
static void appendByte(unsigned char byte, void *_data) {
NSMutableData *data = (__bridge NSMutableData*) _data;
NSLog(#"pre: %#", data);
[data appendBytes:&byte length:1];
NSLog(#"post: %#", data);
}
-(NSData*) PandoraDecrypt:(NSString*) string {
struct blf_ecb_ctx ctx;
NSMutableData *mut = [[NSMutableData alloc] init];
Blowfish_ecb_start(&ctx, FALSE, (unsigned char*) PARTNER_DECRYPT,
sizeof(PARTNER_DECRYPT) - 1, appendByte,
(__bridge void*) mut);
const char *bytes = [string cStringUsingEncoding:NSASCIIStringEncoding];
int len = [string lengthOfBytesUsingEncoding:NSASCIIStringEncoding];
int i;
for (i = 0; i < len; i += 2) {
NSLog(#"%c, %c, %d, %d", bytes[i], bytes[i+1], h2i[(int) bytes[i]] * 16, h2i[(int) bytes[i + 1]]);
Blowfish_ecb_feed(&ctx, h2i[(int) bytes[i]] * 16 + h2i[(int) bytes[i + 1]]);
}
Blowfish_ecb_stop(&ctx);
return mut;
}
And you can use this like:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog(#"%#", [NSString stringWithCString:[
[self PandoraDecrypt:#"aed5c110d793f850521a4dd3a56a70d9"] bytes]
encoding:NSASCIIStringEncoding]);
return YES;
}
So it was mainly a research from my side, pls give credit to implementers of the Blowfish api and the pandora api ;-)
Also my NSLogs are for research purpose, it highlights how the decryption works.

Related

Generating SHA256 in iOS

I tried to generate SHA256 in iOS using Arcane library with following data:
String: Amount=50&BillerID=59&ChannelID=2&Context=34|check|test&ReturnURL=https://uat.myfatoora.com/ReceiptPOC.aspx&TxnRefNum=000000000020003&UserName=DCS
Key: 71DD0F73AFFBB47825FF9864DDE95F3B
Result was 409dc622b3bef5c9fc46e45c3210111fcb4536d3a55833316fe0dc8154b3ea34
which I thought to be correct. However, the Windows counterpart is generating SHA256 using following code:
Windows Phone Source Code:
public static string HmacSha256(string secretKey, string value)
{
var msg = CryptographicBuffer.ConvertStringToBinary(value, BinaryStringEncoding.Utf8);
byte[] convertedHash = new byte[secretKey.Length / 2];
for (int i = 0; i < secretKey.Length / 2; i++)
{
convertedHash[i] = (byte)Int32.Parse(secretKey.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber);
}
// Create HMAC.
var objMacProv = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha256);
CryptographicHash hash = objMacProv.CreateHash(convertedHash.AsBuffer());
hash.Append(msg);
return CryptographicBuffer.EncodeToHexString(hash.GetValueAndReset());
}
and the result is: 94a20ca39c8487c7763823ec9c918d9e38ae83cb741439f6d129bcdef9edba73 which is different from what I got. Can somebody help me with this and let me know what the above code is doing and how can I replicate it in iOS.
Edit:
iOS Source code
let key = self.md5(string: "71DD0F73AFFBB47825FF9864DDE95F3B")
let hash = HMAC.SHA256(str, key: key)
The key here is you need to convert your secret, which is a hex string, into NSData. In other words, NSData byte stream would "look" like the secret.
This should do what you want:
// Hex string to NSData conversion from here http://stackoverflow.com/questions/7317860/converting-hex-nsstring-to-nsdata
NSString *secret = #"71DD0F73AFFBB47825FF9864DDE95F3B";
NSData *dataIn = [#"Amount=50&BillerID=59&ChannelID=2&Context=34|check|test&ReturnURL=https://uat.myfatoora.com/ReceiptPOC.aspx&TxnRefNum=000000000020003&UserName=DCS" dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData *macOut = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
secret = [secret stringByReplacingOccurrencesOfString:#" " withString:#""];
NSMutableData *secretData = [[NSMutableData alloc] init];
unsigned char whole_byte;
char byte_chars[3] = {'\0','\0','\0'};
int i;
for (i=0; i < [secret length]/2; i++) {
byte_chars[0] = [secret characterAtIndex:i*2];
byte_chars[1] = [secret characterAtIndex:i*2+1];
whole_byte = strtol(byte_chars, NULL, 16);
[secretData appendBytes:&whole_byte length:1];
}
CCHmac(kCCHmacAlgSHA256, secretData.bytes, secretData.length, dataIn.bytes, dataIn.length, macOut.mutableBytes);
NSMutableString *stringOut = [NSMutableString stringWithCapacity:macOut.length];
const unsigned char *macOutBytes = macOut.bytes;
for (NSInteger i=0; i<macOut.length; ++i) {
[stringOut appendFormat:#"%02x", macOutBytes[i]];
}
NSLog(#"dataIn: %#", dataIn);
NSLog(#"macOut: %#", macOut);
NSLog(#"stringOut: %#", stringOut);
Output:
2016-09-27 20:18:54.181 JKS[27562:5321334] dataIn: <416d6f75 6e743d35 30264269 6c6c6572 49443d35 39264368 616e6e65 6c49443d 3226436f 6e746578 743d3334 7c636865 636b7c74 65737426 52657475 726e5552 4c3d6874 7470733a 2f2f7561 742e6d79 6661746f 6f72612e 636f6d2f 52656365 69707450 4f432e61 73707826 54786e52 65664e75 6d3d3030 30303030 30303030 32303030 33265573 65724e61 6d653d44 4353>
2016-09-27 20:18:54.181 JKS[27562:5321334] macOut: <94a20ca3 9c8487c7 763823ec 9c918d9e 38ae83cb 741439f6 d129bcde f9edba73>
2016-09-27 20:18:54.181 JKS[27562:5321334] stringOut: 94a20ca39c8487c7763823ec9c918d9e38ae83cb741439f6d129bcdef9edba73
Updated with Swift (code should be cleaned up)
// http://stackoverflow.com/questions/29799361/generate-a-hmac-swift-sdk8-3-using-cchmac
func generateHMAC(key: String, data: String) -> String {
let keyData = key.dataFromHexadecimalString()! as NSData
let dataIn = data.data(using: .utf8)! as NSData
var result: [CUnsignedChar]
result = Array(repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), keyData.bytes, keyData.length, dataIn.bytes, dataIn.length, &result)
let hash = NSMutableString()
for val in result {
hash.appendFormat("%02hhx", val)
}
return hash as String
}
You can use this extension to convert the hex string to Data
// Modified slightly http://stackoverflow.com/questions/26501276/converting-hex-string-to-nsdata-in-swift
extension String {
func dataFromHexadecimalString() -> Data? {
var data = Data(capacity: characters.count / 2)
let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive)
regex.enumerateMatches(in: self, options: [], range: NSMakeRange(0, characters.count)) { match, flags, stop in
let byteString = (self as NSString).substring(with: match!.range)
var num = UInt8(byteString, radix: 16)
data.append(&num!, count: 1)
}
return data
}
}
And to use do something like:
let secret = "71DD0F73AFFBB47825FF9864DDE95F3B"
let value = "Amount=50&BillerID=59&ChannelID=2&Context=34|check|test&ReturnURL=https://uat.myfatoora.com/ReceiptPOC.aspx&TxnRefNum=000000000020003&UserName=DCS"
print("\(generateHMAC(key: secret, data: value))")
Your output should be 94a20ca39c8487c7763823ec9c918d9e38ae83cb741439f6d129bcdef9edba73
You will need #import <CommonCrypto/CommonCrypto.h> in your bridging header.
The Windows code takes the string, interprets it as a hexadecimal number, and converts two characters a time into one byte.
Your Mac code most like takes the string as it is. Since the key starts with "71", your windows code takes that as a single byte with value 0x71 = 129, your Mac code takes it as two bytes with values '7' = 55 and '1' = 49.
All you need to do is convert the bytes on the Mac exactly as you do it on Windows. You might have to do the unthinkable and look at the source code of the Mac library to see how it does the actual hash calculation.
#import <CommonCrypto/CommonHMAC.h>
+ (NSString *)hmacSHA256EncryptString{
NSString * parameterSecret = #"input secret key";
NSString *plainString = #"input encrypt content string";
const char *secretKey = [parameterSecret cStringUsingEncoding:NSUTF8StringEncoding];
const char *plainData = [plainString cStringUsingEncoding:NSUTF8StringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, secretKey, strlen(secretKey), plainData, strlen(plainData), cHMAC);
NSData *HMACData = [NSData dataWithBytes:cHMAC length:sizeof(cHMAC)];
const unsigned char *bufferChar = (const unsigned char *)[HMACData bytes];
NSMutableString *hmacString = [NSMutableString stringWithCapacity:HMACData.length * 2];
for (int i = 0; i < HMACData.length; ++i){
[hmacString appendFormat:#"%02x", bufferChar[i]];
}
return hmacString;
}

iOS (objective-c) compression_decode_buffer() returns zero

I'm converting a very large json result on my server to a compressed format that I can decompress on my objective c app. I would prefer to use the iOS 9 compression lib if possible (libcompression.tbd), described in Apple's CompressionSample/BlockCompression.c sample code.
I'm passing the compressed NSData result to the following method:
#include "compression.h"
...
- (NSData *) getDecompressedData:(NSData *) compressed {
size_t dst_buffer_size = 20000000; //20MB
uint8_t *dst_buffer = malloc(dst_buffer_size);
uint8_t *src_buffer = malloc(compressed.length);
[compressed getBytes:src_buffer length:compressed.length];
size_t decompressedSize = compression_decode_buffer(dst_buffer, dst_buffer_size, src_buffer, compressed.length, nil, COMPRESSION_ZLIB);
NSData *decompressed = [[NSData alloc] initWithBytes:dst_buffer length:decompressedSize];
return decompressed;
}
The compressed parameter has a length that matches my server logs, but the result from compression_decode_buffer is always zero and dst_buffer is not modified. I'm not receiving any errors, and the log has no relevant info.
I've tried ZLIB and LZ4 compression / decompression methods and several libraries on the server side, all with the same result.
What am I doing wrong here?
After much testing and research, I found that the compression library I was using on my server adds a compression header (1st two bytes), per RFC1950. I skipped those two bytes and compression_decode_buffer works like a champ!
- (NSData *) getDecompressedData:(NSData *) compressed {
size_t dst_buffer_size = 20000000; //20MB
uint8_t *dst_buffer = malloc(dst_buffer_size);
uint8_t *src_buffer = malloc(compressed.length);
[compressed getBytes:src_buffer range:NSMakeRange(2, compressed.length - 2)];
size_t decompressedSize = compression_decode_buffer(dst_buffer, dst_buffer_size, src_buffer, compressed.length - 2, nil, COMPRESSION_ZLIB);
NSData *decompressed = [[NSData alloc] initWithBytes:dst_buffer length:decompressedSize];
return decompressed;
}
Thank you so much, azcoastal - saved me heaps of time!
Here's some working Swift code ..
let bytes = [UInt8](data) // Data -> [Uint8]
// Need to remove the first 2 bytes (a header) from the array!!
let slice = bytes[2...bytes.count-1]
let noheader = Array(slice)
let dst_count = bytes.count * MULTIPLY
var dst = [UInt8](repeating: 0, count: dst_count) // destination
let size = compression_decode_buffer(&dst, dst_count,
noheader, noheader.count, nil, COMPRESSION_ZLIB)

Random 256bit key using SecRandomCopyBytes( ) in iOS

I have been using UUIDString as an encrption key for the files stored on my iPAD, but the security review done on my app by a third party suggested the following.
With the launch of the application, a global database key is generated and stored in the keychain. During generation, the method UUIDString of the class NSUUID provided by the iOS is used. This function generates a random string composed of letters A to F, numbers and hyphens and unnecessarily restricts the key space, resulting in a weakening of the entropy.
Since the key is used only by application logic and does not have to be read, understood or processed by an individual, there is no need to restrict the key space to readable characters. Therefore, a random 256-bit key generated via SecRandomCopyBytes () should be used as the master key.
Now I have searched a lot and tried some code implementation but havent found the exact thing.
What I have tried:
NSMutableData* data = [NSMutableData dataWithLength:32];
int result = SecRandomCopyBytes(kSecRandomDefault, 32, data.mutableBytes);
NSLog(#"Description %d",result);
My understanding is that this should give me an integer and I should convert it to an NSString and use this as my key, but I am pretty sure that this is not what is required here and also the above method always gives the result as 0. I am completely lost here and any help is appreciated.
Thanks.
The result of SecRandomCopyBytes should always be 0, unless there is some error (which I can't imagine why that might happen) and then the result would be -1. You're not going to convert that into a NSString.
The thing you're trying to get are the random bytes which are being written into the mutable bytes section, and that's what you'll be using as your "master key" instead of the UUID string.
The way I would do it would be:
uint8_t randomBytes[16];
int result = SecRandomCopyBytes(kSecRandomDefault, 16, randomBytes);
if(result == 0) {
NSMutableString *uuidStringReplacement = [[NSMutableString alloc] initWithCapacity:16*2];
for(NSInteger index = 0; index < 16; index++)
{
[uuidStringReplacement appendFormat: #"%02x", randomBytes[index]];
}
NSLog(#"uuidStringReplacement is %#", uuidStringReplacement);
} else {
NSLog(#"SecRandomCopyBytes failed for some reason");
}
Using a UUIDString feels secure enough to me, but it sounds like your third party security audit firm is trying really hard to justify their fees.
EDITED: since I'm now starting to collect downvotes because of Vlad's alternative answer and I can't delete mine (as it still has the accepted checkmark), here's another version of my code. I'm doing it with 16 random bytes (which gets doubled in converting to Hex).
The NSData generated does not guarantee UTF16 chars.
This method will generate 32byte UTF string which is equivalent to 256bit. (Advantage is this is plain text and can be sent in GET requests ext.)
Since the length of Base64 hash is = (3/4) x (length of input string) we can work out input length required to generate 32byte hash is 24 bytes long. Note: Base64 may pad end with one, two or no '=' chars if not divisible.
With OSX 10.9 & iOS 7 you can use:
-[NSData base64EncodedDataWithOptions:]
This method can be used to generate your UUID:
+ (NSString*)generateSecureUUID {
NSMutableData *data = [NSMutableData dataWithLength:24];
int result = SecRandomCopyBytes(NULL, 24, data.mutableBytes);
NSAssert(result == 0, #"Error generating random bytes: %d", result);
NSString *base64EncodedData = [data base64EncodedStringWithOptions:0];
return base64EncodedData;
}
A UUID is a 16 bytes (128 bits) unique identifier, so you aren't using a 256 bits key here. Also, as #zaph pointed out, UUIDs use hardware identifiers and other inputs to guarantee uniqueness. These factors being predictable are definitely not cryptographically secure.
You don't have to use a UUID as an encryption key, instead I would go for a base 64 or hexadecimal encoded data of 32 bytes, so you'll have your 256 bit cryptographically secure key:
/** Generates a 256 bits cryptographically secure key.
* The output will be a 44 characters base 64 string (32 bytes data
* before the base 64 encoding).
* #return A base 64 encoded 256 bits secure key.
*/
+ (NSString*)generateSecureKey
{
NSMutableData *data = [NSMutableData dataWithLength:32];
int result = SecRandomCopyBytes(kSecRandomDefault, 32, data.mutableBytes);
if (result != noErr) {
return nil;
}
return [data base64EncodedStringWithOptions:kNilOptions];
}
To answer the part about generate UUID-like (secure) random numbers, here's a good way, but remember these will be 128 bits only keys:
/** Generates a 128 bits cryptographically secure key, formatted as a UUID.
* Keep that you won't have the same guarantee for uniqueness
* as you have with regular UUIDs.
* #return A cryptographically secure UUID.
*/
+ (NSString*)generateCryptoSecureUUID
{
unsigned char bytes[16];
int result = SecRandomCopyBytes(kSecRandomDefault, 16, bytes);
if (result != noErr) {
return nil;
}
return [[NSUUID alloc] initWithUUIDBytes:bytes].UUIDString;
}
Cryptography is great, but doing it right is really hard (it's easy to leave security breaches). I cannot recommend you more the use of RNCryptor, which will push you through the use of good encryption standards, will make sure you're not unsafely reusing the same keys, will derivate encryption keys from passwords correctly, etc.
And i try this code for length 16 and bytes 16 :
uint8_t randomBytes[16];
NSMutableString *ivStr;
int result = SecRandomCopyBytes(kSecRandomDefault, 16, randomBytes);
if(result == 0) {
ivStr = [[NSMutableString alloc] initWithCapacity:16];
for(NSInteger index = 0; index < 8; index++)
{
[ivStr appendFormat: #"%02x", randomBytes[index]];
}
NSLog(#"uuidStringReplacement is %#", ivStr);
} else {
NSLog(#"SecRandomCopyBytes failed for some reason");
}
Successful
Since the Key usually needs to be UTF-8 encoded and "readable" - i.e. with no UTF-8 control characters- I decided to filter the randomly generated bytes generated using SecRandomCopyBytes so it'd only have characters from the Basic Latin Unicode block.
/*!
* #brief Generates NSData from a randomly generated byte array with a specific number of bits
* #param numberOfBits the number of bits the generated data must have
* #return the randomly generated NSData
*/
+ (NSData *)randomKeyDataGeneratorWithNumberBits:(int)numberOfBits {
int numberOfBytes = numberOfBits/8;
uint8_t randomBytes[numberOfBytes];
int result = SecRandomCopyBytes(kSecRandomDefault, numberOfBytes, randomBytes);
if(result == 0) {
return [NSData dataWithBytes:randomBytes length:numberOfBytes];
} else {
return nil;
}
}
/*!
* #brief Generates UTF-8 NSData from a randomly generated byte array with a specific number of bits
* #param numberOfBits the number of bits the generated data must have
* #return the randomly generated NSData
*/
+ (NSData *)randomKeyUTF8DataGeneratorWithNumberBits:(int)numberOfBits {
NSMutableData *result = [[NSMutableData alloc] init];
int numberOfBytes = numberOfBits/8;
while (result.length < numberOfBytes) {
// Creates a random byte
NSData *byte = [self randomKeyDataGeneratorWithNumberBits:8];
int asciiValue = [[[NSString alloc] initWithData:byte encoding:NSUTF8StringEncoding] characterAtIndex:0];
// Checks if the byte is UTF-8
if (asciiValue > 32 && asciiValue < 127) {
[result appendData:byte];
}
}
return result;
}
If you want to make your key a little more "readable" you can try and make it Base64 URL Safe
/*!
* #brief Encodes a String Base 64 with URL and Filename Safe Alphabet
* #discussion Base64url Encoding The URL- and filename-safe Base64 encoding described in RFC 4648 [RFC4648] (https://tools.ietf.org/html/rfc4648)
* #discussion Section 5 (https://tools.ietf.org/html/rfc4648#section-5)
* #param string the string to be enconded
* #return the encoded string
*/
+ (NSString *)base64URLandFilenameSafeString:(NSString *)string {
NSString *base64String = string;
base64String = [base64String stringByReplacingOccurrencesOfString:#"/"
withString:#"_"];
base64String = [base64String stringByReplacingOccurrencesOfString:#"+"
withString:#"-"];
return base64String;
}
Generate a UTF-8 256 bits key:
NSData *key = [self randomKeyUTF8DataGeneratorWithNumberBits:256];
NSString *UTF8String = [[NSString alloc] initWithBytes:[key bytes] length:data.length encoding:NSUTF8StringEncoding];
NSString *base64URLSafeString = [self base64URLandFilenameSafeString:UTF8String];

Decrypting data, using aes gcm with the openssl evp interface in IOS

I've got the following code for decrypting the data:
-(NSString*)_decrypte:(NSString*)encrypted
{
NSString *decrypted;
NSData *enc = [[NSData alloc]initWithBase64EncodedString:encrypted options:0];
int len = (int)[enc length];
Byte *cipher = (Byte*)malloc(len);
memcpy((void *)cipher, [enc bytes], len);
Byte *iv = toIv(_ivCounter++, 16);
for(uint i = 0; i < 16; i++)
{
iv[i] = 0;
}
int outLen, plainttext_len, dec_success, tag_len = 128 / 8;
unsigned char *plaintext = (unsigned char*)malloc(len);
unsigned char *tag =(unsigned char*)malloc(tag_len);
int offset = len - (tag_len);
for(int i = 0; i < tag_len; i++)
{
tag[i] = cipher[i + offset];
}
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, (void *)tag);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL);
EVP_DecryptInit_ex(ctx, NULL, NULL, _sesKey, iv);
EVP_DecryptUpdate(ctx, NULL, &len, NULL, 0);
EVP_DecryptUpdate(ctx, plaintext, &outLen, cipher, len);
plainttext_len = outLen;
dec_success = EVP_DecryptFinal_ex(ctx, plaintext + outLen, &outLen);
EVP_CIPHER_CTX_free(ctx);
decrypted = [NSString stringWithFormat:#"%s", plaintext];
return decrypted;
}
For some reason the code doesn't decrypt the data right. The _sesKey is right and the IV is overwritten after the call to toIV to force the right iv for the first set of data and there is no AAD data needed for the decrypting. I've already done this in android(using the bouncycastle library), so I known for a fact that the _sesKey and the IV are correct. I don't know if anybody can help me by telling what goes wrong and why.
I found the mistake with some help, the problem is that the variable _sesKey was a pointer and during generating the key and decrypting the data, the memory the pointer was pointing to got whiped. So the _sesKey became invalid. So now a changed _sesKey to a normal byte array and now it works.

NSString to Emoji Unicode

I am trying to pull an JSON file from the backend containing unicodes for emoji. These are not the legacy unicodes (example: \ue415), but rather unicodes that work cross platform (example: \U0001F604).
Here is a sample piece of the json getting pulled:
[
{
"unicode": "U0001F601",
"meaning": "Argh!"
},
{
"unicode": "U0001F602",
"meaning": "Laughing so hard"
}
]
I am having difficulty converting these strings into unicodes that will display as emoji within the app.
Any help is greatly appreciated!
In order to convert these unicode characters into NSString you will need to get bytes of those unicode characters.
After getting bytes, it is easy to initialize an NSString with bytes. Below code does exactly what you want. It assumes jsonArray is the NSArray generated from your json getting pulled.
// initialize using json serialization (possibly NSJSONSerialization)
NSArray *jsonArray;
[jsonArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSString *charCode = obj[#"unicode"];
// remove prefix 'U'
charCode = [charCode substringFromIndex:1];
unsigned unicodeInt = 0;
//convert unicode character to int
[[NSScanner scannerWithString:charCode] scanHexInt:&unicodeInt];
//convert this integer to a char array (bytes)
char chars[4];
int len = 4;
chars[0] = (unicodeInt >> 24) & (1 << 24) - 1;
chars[1] = (unicodeInt >> 16) & (1 << 16) - 1;
chars[2] = (unicodeInt >> 8) & (1 << 8) - 1;
chars[3] = unicodeInt & (1 << 8) - 1;
NSString *unicodeString = [[NSString alloc] initWithBytes:chars
length:len
encoding:NSUTF32StringEncoding];
NSLog(#"%# - %#", obj[#"meaning"], unicodeString);
}];

Resources