Objective-C Base64 decoding returns nil - objective-c

I have downloaded and added the following category into my project: https://github.com/nicklockwood/Base64
NSString *secret = #"7pgj8Dm6";
NSString *decodedSecret = [secret base64DecodedString];
NSLog(#"decoded Secret = %#", decodedSecret);
This however, always turns out to be nil. What is happening here ?

I hope it will helpful to you
NSString *decodeString = #"Raja";
Encode String
NSData *encodeData = [decodeString dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [encodeData base64EncodedStringWithOptions:0];
DLog(#"Encode String Value: %#", base64String);
Decode String
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
NSString *decodedString = [[NSString alloc] initWithData:decodedData encoding:NSUTF8StringEncoding];
DLog(#"Decode String Value: %#", base64String);
Thanks

I've failed to relax iOS native base64 decoder enough with NSDataBase64DecodingIgnoreUnknownCharacters to process jwt payloads
so I had to revert to a 3rdparty MF_Base64Codec
Sadly you might want to consider doing the 3rdparty route
until Apple will have fixed the bug or relaxed the decoder further to
accept what it currently considers crap input

Your input 7pgj8Dm6is an Invalid base64 encoded string. So the result will be always nil since the method base64DecodedString used only for UTF8 encoding.
As of iOS 7 and Mac OS 10.9, this library is not longer needed.
You can use initWithBase64EncodedString:options:
The default implementation of this method will reject non-alphabet characters, including line break characters. To support different encodings and ignore non-alphabet characters, specify an options value of NSDataBase64DecodingIgnoreUnknownCharacters.

Related

AES256 CBC encryption/decryption in objective C. Getting null value in decryption. I am already having the encrypted value with me

// Code to decrypt value
{
NSString *dataString = #"8T79ubuRfEwpfSOO1yr3Q+nbsla4J7VqFCe4THnPOGxjk37+2QgdLUgq5yWqLtx+";
NSString *base64Key = #"82a645babc6vd41c9a2cb4d0d3ba17ad";
NSString *base64KeyIv = #"acf30ad62b693849";
NSData *key = [[NSData alloc] initWithBase64EncodedString:base64Key options:0];
NSData *keyiv = [[NSData alloc] initWithBase64EncodedString:base64KeyIv options:0];
NSData *data = [[NSData alloc] initWithBase64EncodedString:dataString options:0];
NSData *encryptedData = [ViewController crypt:data
iv:keyiv
key:key
context:kCCDecrypt];
NSString *decryptText = [[NSString alloc] initWithData:encryptedData
encoding:NSUTF8StringEncoding];
NSLog(#"Decrypted Result: %#", decryptText); //here getting NULL
}
I am getting null value while decryption.Please help me where I am wrong. AES256 CBC encryption/decryption in objective C. Getting null value in decryption. I am already having the encrypted value with me.
There are likely several errors here, and it's unclear what your -crypt:iv:key:context: method does. Do you know for certain that your encryption system exactly matches your -crypt:iv:key:context: method?
At a start, you're getting nil because the output isn't UTF-8 (because it's almost certainly corrupted due to passing the wrong key and IV).
Next, your crypt method should be generating errors because what you're passing is invalid, so you need to check those errors. They would likely tell you what's wrong.
At a minimum, you are decoding the key and IV incorrectly. If they're in Base64, they're the wrong length. They look like they're just UTF-8/ASCII encoded (which is a security issue, but your system may just be insecure). In Base64, this key is 24 bytes, while in ASCII it's 32 bytes (which is the correct key length).
If that's the only problem, then the fix would be:
NSData *key = [base64Key dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyiv = [base64KeyIv dataUsingEncoding:NSUTF8StringEncoding];
(Ideally you'd rename the "base64..." identifier since these aren't Base64 encoded. dataString does appear to be Base64 encoded.)

initWithBase64EncodedString return nil

My resultString is 'PHNhbWxwOlJlc3BvbnNlIH...c3BvbnNlPgoK' and when i am decoding it shows me decodedData as nil.
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:resultString options:0];
I also tried this string with https://www.base64decode.org/ ,
it successfully shows results.
What wrong here in decoding ?
Probably you have some invalid characters in your string, like padding new lines. Try to pass NSDataBase64DecodingIgnoreUnknownCharacters option instead of 0.
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:resultString options:NSDataBase64DecodingIgnoreUnknownCharacters];
Almost certainly your string is not valid Base64, but that it is "close enough" that base64decode.org accepts it. The most likely cause is that you've dropped a trailing =. base64decode.org is tolerant of that, and just quietly throws away what it can't decode (the last byte in that case). NSData is not tolerant of that, because it's not valid Base64.
base64decode.org is also tolerant of random non-base64 characters in the string and just throws them away. NSData is not (again, sine it's invalid).
Try this! Simple solution :) Must need Foundation.framework. By default initWithBase64EncodedString method returns nil when the input is not recognized as valid Base-64. Please check your string is a valid Base-64 type or not!
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:#"eyJuYW1lIjoidmlnbmVzaCJ9" options:0];
NSError *dataError;
NSDictionary* responseObject = [NSJSONSerialization JSONObjectWithData:decodedData
options:kNilOptions
error:&dataError];
if(dataError == nil) {
NSLog(#"Result %#",responseObject);
}

Objective C: AES 256 Encryption with NSData Key

Previously I did Triple DES encryption to encrypt some data using a string key file, by defining a method
+ (NSData *)tripleDESEncryptWithKey:(NSString *)key dataToEncrypt:(NSData*)convertedData {}.
Now, similarly I am doing AES 256 encryption. But this time, I can not use a string as the key. I need to get NSData from a file in resources using
NSData *keyData = [NSData dataWithContentsOfFile:keyPath];
As I need to pass this key as parameter, I tried to convert it into string with
NSString *key = [[NSString alloc] initWithData:keyData encoding:NSUTF8StringEncoding];
but it returned NULL. So, How to use the Data key for AES 256 encryption ?
EDIT: I got that I should not use UTF8 encoding as the data file was made by Base64 encoding of a string. So Now the question is, how to get the string key using Base64 from keyData ?
If key variable returned NULL. Try to use like this.
NSString* key = [NSString stringWithUTF8String:[keyData bytes]];
Refer to KennyTM's Answer
UPDATE 1: You can also read the string directly from your file without convert in NSData
By NSFileHandle:
NSString * path = #"your key file path";
NSFileHandle * fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
NSData * buffer = nil;
while ((buffer = [fileHandle readDataOfLength:1024])) {
//do something with buffer
}
or use NSString
NSString * key = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
Refer to Dave DeLong's Answer
Note: Ensure your keyPath variable , Is it correct in the format of full or relative path?
UPDATE 2: You can also deal with Base64 Encoding with Matt Gallagher NSData+Base64 Class&Header (See also his blog there)
For encode base64
NSString * key = [[path dataUsingEncoding:NSUTF8StringEncoding] base64EncodedString];
Hope it helps you!
Read the file:
NSData* myData = [NSData dataWithContentsOfFile:myFileWithPath];
Then use one of the implementations in this post:
Base64 encoding options on the Mac and iPhone
to do your Base64 conversion.
Note: simply sticking your decryption key into a file is a bad idea. Optimally, the key would be stored securely by being encrypted by the user's own key.

Parsing arabic text with SBJson in Xcode

i have a JSON file that i'm trying to parse using SBJson.
the response string that i'm receiving is displaying arabic characters correctly when i do a
NSLog(#"%#",responseString);
but whenever i use the SBJson parser
NSDictionary *myDictionary = [responseString JSONValue];
and try
NSLog(#"%#", myDictionary);
my arabic characters are transformed to something weird:
\U0633\U0627\U0642\U064a\U0629 \U0627\U0644\U0645\U0633\U0643
please can anyone help
Don't worry. All is well.
\u0633
is equivalence to
س
try this in C++:
std::wstring tStr = L"\u0633";
tStr will equal to س
Just NSLog is not converting
use this :
NSStringEncoding Arabicencoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsArabic);
NSString *yourstring = [[NSString alloc]initWithData:yourdata encoding:Arabicencoding];
"\U0633\U0627\U0642\U064a\U0629 \U0627\U0644\U0645\U0633\U0643" is actually just the encoding that Objective-C uses for none ascii characters. Try adding a subview/label on whatever you're testing with which will display the text. First try with "responseString" and then "myDictionary" it could display the same.

Decoding word-encoded Content-Disposition header file name in Objective-C

I am trying to retrieve a file name that can't be represented in ASCII from the content-disposition header.
This file name is word-encoded. Below is the encoded file name:
=?UTF-8?Q?=C3=ABst=C3=A9_=C3=A9_=C3=BAm_n=C3=B4m=C3=A9?= =?UTF-8?Q?_a=C3=A7ent=C3=BAad=C3=B5.xlsx?=
How do I get the decoded file name (that actually is "ësté é úm nômé açentúadõ.xlsx")?
PS: I am looking for an Objective-C implementation.
You probably want to search for a MIME handling framework, but I searched online and came up with nothing, so....
I couldn't find an example online, so I'm just showing the algorithm here. It's not the best example since I'm making a big assumption. That being that the string is always UTF-8 Q-encoded.
Q-encoding is like URL-encoding (percent-encoding), which Foundation's NSString already has support for decoding. The only (practical) difference when decoding (there are bigger differences when encoding) is that % encodings are = encodings instead.
Then there's the lead-in and lead-out stuff. Each encoded block has the format =?charset-name?encoding-type? ... encoded string here ... ?=. You should really read the charset name is use that encoding, and you should really read the encoding-type, since it may be "Q" or "B" (Base64).
This example only works for Q-encoding (a subset of quoted-printable). You should be able to easily modify it to handle the different charsets and to handle Base64 encoding however.
#import <Foundation/Foundation.h>
int main(void) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *encodedString = #"=?UTF-8?Q?=C3=ABst=C3=A9_=C3=A9_=C3=BAm_n=C3=B4m=C3=A9?= =?UTF-8?Q?_a=C3=A7ent=C3=BAad=C3=B5.xlsx?=";
NSScanner *scanner = [NSScanner scannerWithString:encodedString];
NSString *buf = nil;
NSMutableString *decodedString = [[NSMutableString alloc] init];
while ([scanner scanString:#"=?UTF-8?Q?" intoString:NULL]
|| ([scanner scanUpToString:#"=?UTF-8?Q?" intoString:&buf] && [scanner scanString:#"=?UTF-8?Q?" intoString:NULL])) {
if (buf != nil) {
[decodedString appendString:buf];
}
buf = nil;
NSString *encodedRange;
if (![scanner scanUpToString:#"?=" intoString:&encodedRange]) {
break; // Invalid encoding
}
[scanner scanString:#"?=" intoString:NULL]; // Skip the terminating "?="
// Decode the encoded portion (naively using UTF-8 and assuming it really is Q encoded)
// I'm doing this really naively, but it should work
// Firstly I'm encoding % signs so I can cheat and turn this into a URL-encoded string, which NSString can decode
encodedRange = [encodedRange stringByReplacingOccurrencesOfString:#"%" withString:#"=25"];
// Turn this into a URL-encoded string
encodedRange = [encodedRange stringByReplacingOccurrencesOfString:#"=" withString:#"%"];
// Remove the underscores
encodedRange = [encodedRange stringByReplacingOccurrencesOfString:#"_" withString:#" "];
[decodedString appendString:[encodedRange stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
NSLog(#"Decoded string = %#", decodedString);
[decodedString release];
[pool drain];
return 0;
}
This outputs:
chrisbook-pro:~ chris$ ./qp-decode
2010-12-01 18:54:42.903 qp-decode[9643:903] Decoded string = ësté é úm nômé açentúadõ.xlsx
Created an easier / successful method here using a trick involving NSString percent escapes..
https://stackoverflow.com/a/10888548/285694
I recently implemented a NSString category that decodes MIME Encoded-Word with either Q-encoding or B-encoding.
The code is available on GitHub and is briefly explained in this answer.