I need to undergo a process of creating a signature from the following process in Objective C:
ASCII encode an NSString
Hash the results with MD5
Perform bitwise operation on the resulting bytes (&127)
Convert to Base64 string
I am stuck on where to start. I am able to complete this task in C# but am at a loss in Objective C or even ANSI C.
I have got as far as getting the UTF8String from the initial NSString using:
[NSString UTF8String]
Hopefully you can help.
Read String Conversions
Dowload NSString MD5 Category by H2CO3
Take your pick of Base64 encoders
You mentioned you are having problems with String conversions, this is what you want to convert to ASCII:
NSString* src = #"";
NSData* data = [src dataUsingEncoding: NSASCIIStringEncoding allowLossyConversion: YES];
NSString* ascii = [[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding];
To perform the bitwise operations is a little complicated. You will want to do this in straight C, like so:
NSString* src = <MD5 hashed result>
NSMutableString* dst = [[NSMutableString alloc] initWithCapacity: src.length];
for(NSUInteger i=0;i<src.length;i++) {
unichar c = [src characterAtIndex: i];
[dst appendFormat: #"%d", (c & 127)];
}
//Base64 encode dst
The 3rd party should tell you how to do it if they require it.
Related
I am building a simple iphone (SDK6.1) application that encrypts some user's notes, stores the into a database and when user enters a password (does not need to be encrypted) it will decrypt his notes and show them to him.
For the database i am using Core Data (.xcdatamodel). The encrypted text at the moment is declared as String in the data model and in the Notes.h fil,e it is declared as NSString.
For the Encryption i am using apple's sample code from CryptoExercise which works perfectly.
The problem is that when i try to save the encrypted text in the database and then decrypt it i am not getting the desired results.. basically i am getting an empty string back.
Obviously i am using the following code to convert from uint8_t to NSString so i can store it into the data model and i understand that this is my main problem.
uint8_t *cipherBuffer = NULL;
SecKey *encrypt = [[SecKey alloc]init];
NSString *et = [[NSString alloc]init];
[encrypt generateKeyPairRSA];
// Encrypt the plain text
cipherBuffer = [encrypt Encryption:plainTextField.text];
// Convert uint8_t to NSString
NSMutableData *data = [[NSMutableData alloc]init];
[data appendBytes:cipherBuffer length:strlen((char*)cipherBuffer)+1];
NSString *string = [[NSString alloc]initWithData:data encoding: NSASCIIStringEncoding];
// Save to Data Model
[self.currentNote setEncryptedText:string];
[self.delegate addNewNoteViewControllerDidSave];
// Retrieve encrypted text from database
et = [self.currentNote encryptedText];
// Convert back to uint_8
NSData *someData = [et dataUsingEncoding:NSUTF8StringEncoding];
const void *bytes = [someData bytes];
uint8_t *crypto_data = (uint8_t*)bytes;
// Decrypt Data
[encrypt Decryption:crypto_data];
As i said before i understand that converting uint8_t is the main problem here and i would like to know which is the correct way to do this?
Is it possible with Data Model at all, or should i go to SQLite??
You cannot convert arbitrary bytes sequences to NSString and back like that. For example,
if data contains the single byte 128 (hex 0x80), then
NSString *string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
creates a string with one Unicode character U+0080. When you convert this back to NSData with
NSData *d1 = [string dataUsingEncoding:NSUTF8StringEncoding];
then d1 will contain the bytes 0xC2 0x80 (which is the UTF-8 for U+0080). But
NSData *d2 = [string dataUsingEncoding:NSASCIIStringEncoding];
does also not work (d2 = nil), because the string cannot be converted to 7-bit
ASCII.
So you should either
store the encrypted data as "Binary Data" in Core Data, or
store the encrypted data as String, but choose a different conversion strategy,
for example Base64.
So just to answer the question so i can use code and everything..
I changed the EncryptedText in the Data Model to Binary Data and then the code would look like this:
uint8_t *cipherBuffer = NULL;
SecKey *encrypt = [[SecKey alloc]init];
[encrypt generateKeyPairRSA];
cipherBuffer = [encrypt Encryption:plainTextField.text];
NSMutableData *data = [[NSMutableData alloc]init];
[data appendBytes:cipherBuffer length:strlen((char*)cipherBuffer)+1];
// Save cipher into the Data Model
[self.currentNote setEncryptedText:data];
[self.delegate addNewNoteViewControllerDidSave];
// Retrieve cipher back from Data Model
NSData *etData = [[NSData alloc]init];
etData = [self.currentNote encryptedText];
// Convert back to uint8_t
const void *bytes = [etData bytes];
uint8_t *crypto_data = (uint8_t*)bytes;
// De cypher
[encrypt Decryption:crypto_data];
I am encoding NSString input using the following code (CC_SHA256). Could someone help me retrieving in decoded format using the same logic?
-(NSString*) encodeAndGetHashInfo :(NSString *) inStringToHashIt
{
NSDate *currentDate = [NSDate date];
NSLog(#"currentDate %#",currentDate);
NSTimeInterval currTimeMillsecs = ([currentDate timeIntervalSince1970] * 1000);
NSString *strCurrTimeMilliSecs = [NSString stringWithFormat:#"%.0f", currTimeMillsecs];
NSLog(#"strCurrTimeMilliSecs: %#", strCurrTimeMilliSecs); //here we are getting millsec in this way 1328962624994.734131
//double currentTime=[strCurrTimeMilliSecs doubleValue];
//Do hashing
NSString *withSalt= [NSString stringWithFormat:#"%#%#%#", strCurrTimeMilliSecs, inStringToHashIt,STATIC_HASH];
NSLog(#"withSalt.%#",withSalt);
NSString *inputStr = withSalt;
unsigned char hashedChars[32];
CC_SHA256([inputStr UTF8String],
[inputStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding],
hashedChars);
NSData * hashedData = [NSData dataWithBytes:hashedChars length:32];
NSLog (#"hashedData:%#",hashedData );
NSString* hashPasswordResponse = NULL;
hashPasswordResponse = [NSString stringWithFormat:#"%#", hashedData];
hashPasswordResponse = [hashPasswordResponse stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"hashPasswordResponse.......%#",hashPasswordResponse);//this string is
return hashPasswordResponse;
}
You can't SHA is a hashing algoritm, not ment to be decoded.
Like Jonathan Grynspan said, if you could decode sha (any version) would defeat the purpose of such an algorithm.
As the others have noted, SHA-1 and the SHA-2 variants are by design one-way hashes. If you can reverse them, the hashes are broken. The hashes are designed to check data integrity, not to provide data encryption.
If you want encryption/decryption as opposed to hashing, you want to use one of CommonCrypto's CCCryptor routines. See:
Any cocoa source code for AES encryption decryption?
I have done something like:
NSData *dt = [mystr dataUsingEncoding:NSWindowsCP1251StringEncoding];
NSString *str = [NSString alloc] initWithData:dt encoding:NSUTF8StringEncoding];
then NSLog(#"%#", str);
However, if 'mystr' is english then the NSLog would print it as is, but if mystr is Arabic (for ex.) NSLog will not print anything, so how can i change the encoding of mystr to UTF8 ?
thank you in advance.
Your first line creates some data that is in cp1251 encoding. Your second line says "read this data into a string, assuming that the bytes represent a UTF8 encoded string". But because the bytes represent a cp1251 encoded string, that's not likely to work very well.
NSString represents an ordered collection of characters. Internally it uses some encoding to store these characters in memory, but its interface provides an encoding-independent access to the string and you can therefore consider NSString to be encoding-agnostic. If what you want is a collection of bytes that represent the string in UTF8 encoding, then you don't want an NSString. You want to get an NSString to emit such a collection of bytes, perhaps using the -dataUsingEncoding: method you've already found.
Try this one
NSString *s = #"Some string";
const char *c = [s UTF8String];
import
#import "NSString+URLEncoding.h" and
#import "NSString+URLEncoding.m" files
after that where u r doing encode write in .h file this method
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding;
after that write in .m file method implementation
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding
{
return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding)));
}
after that use like this
NSString *keyword=#"sample text";
here pass ur string whatever
NSString *url = [NSString stringWithFormat:#"%#",[keyword urlEncodeUsingEncoding:NSUTF8StringEncoding]];
NSLog(#"%#",url);
Did you try [mystr UTF8String] ? This returns a char *
You can try this
1) NSString to NSData(NSWindowsCP1251StringEncoding
NSString *text=#"This is Sample Text Conversion.....";
NSData *data=[text dataUsingEncoding:NSWindowsCP1251StringEncoding];
2)Revers process.
NSString *textRev=[[NSString alloc]initWithData:data encoding:NSWindowsCP1251StringEncoding];
NSLog(#" Actual String.. %#",textRev);
When I get a string of the form \u043F\u043F (Unicode), how do I convert it to a readable NSUT8String? Here is my code (that fails when these are non English characters):
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSString *theStr = [[NSString alloc] initWithBytes:[receivedData bytes]
length:[receivedData length] encoding: NSUTF8StringEncoding];
NSLog(theStr);
}
When the string is in English characters everything is fine - but when it is in Unicode format it fails to give me a readable string (but remains in a Unicode format).
What do you think?
EDIT:
I realized I didn't give enough info on what I'm trying to do. I am trying to use youtube's way of getting auto-suggested keywords when you use the search box (nothing official, just used a sniffer to find out). Here it is:
http://suggestqueries.google.com/complete/search?hl=en&client=youtube&hjson=t&ds=yt&jsonp=window.yt.www.suggest.handleResponse&q=*******&cp=******
q is your query and cp is the length of q.
So basically when q is something in English it works fine. But when q has non English characters (Russian for example) this is what I get (from NSLog):
window.yt.www.suggest.handleResponse(["\u043F\u0440",[["\u043F\u0440\u0438\u043A\u043E\u043B\u044B","","0"],["\u043F\u0440\u043E\u0436\u0435\u043A\u0442\u043E\u0440\u043F\u0435\u0440\u0438\u0441\u0445\u0438\u043B\u0442\u043E\u043D","","1"],["\u043F\u0440\u043E\u0436\u0435\u043A\u0442\u043E\u0440\u043F\u0435\u0440\u0438\u0441\u0445\u0438\u043B\u0442\u043E\u043D 87","","2"],["\u043F\u0440\u043E\u0436\u0435\u043A\u0442\u043E\u0440\u043F\u0435\u0440\u0438\u0441\u0445\u0438\u043B\u0442\u043E\u043D 88","","3"],["\u043F\u0440\u043E\u0436\u0435\u043A\u0442\u043E\u0440\u043F\u0435\u0440\u0438\u0441\u0445\u0438\u043B\u0442\u043E\u043D 86","","4"],["\u043F\u0440\u043E\u0436\u0435\u043A\u0442\u043E\u0440\u043F\u0435\u0440\u0438\u0441\u0445\u0438\u043B\u0442\u043E\u043D 85","","5"],["\u043F\u0440\u043E\u0436\u0435\u043A\u0442\u043E\u0440\u043F\u0435\u0440\u0438\u0441\u0445\u0438\u043B\u0442\u043E\u043D 89","","6"],["\u043F\u0440\u043E\u0436\u0435\u043A\u0442\u043E\u0440\u043F\u0435\u0440\u0438\u0441\u0445\u0438\u043B\u0442\u043E\u043D 84","","7"],["\u043F\u0440\u0438\u043A\u043E\u043B\u044B \u0432 \u043F\u0440\u044F\u043C\u043E\u043C \u044D\u0444\u0438\u0440\u0435","","8"],["\u043F\u0440\u043E\u0436\u0435\u043A\u0442\u043E\u0440\u043F\u0435\u0440\u0438\u0441\u0445\u0438\u043B\u0442\u043E\u043D 90","","9"]],{}])
You can use:
#interface NSString
{
- (__strong const char *)UTF8String; // Convenience to return
// null-terminated UTF8 representation
}
I think this may help..
NSString *yourString = "\u043F\u0440\u0438\u043A\u043E\u043B\u044B";
NSArray *unicodeArray = [yourString componentsSeparatedByString:#"\\u"];
NSMutableString *finalString = [[NSMutableString alloc] initWithString:#""];
for (NSString *unicodeString in unicodeArray) {
if (![unicodeString isEqualToString:#""]) {
unichar codeValue;
[[NSScanner scannerWithString:unicodeString] scanHexInt:&codeValue];
NSString* betaString = [NSString stringWithCharacters:&codeValue length:1];
[finalString appendString:betaString];
}
}
//finalString should have encoded one
I want to decode an UT8 encoded string.
The input string is "øæ-test-2.txt"
and after decoding it should become
"øæ-test-2.txt"
I found many API to encode the NSString or NSData to UT8 (NSUTF8StringEncoding) but was not able to find the way to decode it.
What I have tried until now:-
NSString *str = [[NSString alloc] initWithUTF8String:[strToDecode cStringUsingEncoding:NSUTF8StringEncoding]];
AND
[strToDecode stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
AND
[NSString stringWithUTF8String:[strToDecode cStringUsingEncoding:[NSString defaultCStringEncoding]]]
I have tried the same input string and I get the proper output in third party decoder.
But was not able to get success
Any hint in right direction would be highly appreciated.
I use this one.
NSString *encoded_string = #"ü";
const char *ch = [encoded_string cStringUsingEncoding:NSISOLatin1StringEncoding];
NSString *decode_string = [[NSString alloc]initWithCString:ch encoding:NSUTF8StringEncoding];
NSLog(#"%#",decode_String)
[NSString stringWithUTF8String:]