How to assign NSString directly to NSMutableData? - nsstring

I am developing an application including sqlite database. I want to encrypt and decrypt data's inside the database using AES encryption. I have successfully implemented the AES encryption and inserted the encrypted data's in the database. And am fetching the data's into a NSString.
Then how can I assign that string without changing the string value into a NSMutableData. Because I want to pass that data to AES decrypt method.

Here is some example of NSString <-> NSData conversion:
NSString *someString = #"string";
//NSString to NSData
NSData* data=[someString dataUsingEncoding: [NSString defaultCStringEncoding]];
//NSData to NSString
someString = [[NSString alloc] initWithData:data encoding:[NSString defaultCStringEncoding]];
NSLog(#"%#", someString);

NSString *someString= #"This string will be converted to mutableData in the next line";
NSMutableData *someData = [[someString dataUsingEncoding:NSUTF8StringEncoding] mutableCopy];

Related

How does libsodium generate a keypair

For public key encryption and diffie-hellman in libsodium, I typically make private keys simply by generating 32 random bytes with randombytes_buf and then derive the public key (when needed) using crypto_scalarmult_base.
Is there any benefit to using crypto_box_keypair to generate a keypair (other than syntax)? Or does this function basically do exactly that?
This is exactly what the crypto_box_keypair() function does.
The benefits of this function are clarity, and guarantee that the secret key is properly generated.
https://download.libsodium.org/doc/public-key_cryptography/public-key_signatures.html
for example:
unsigned char pk[crypto_sign_PUBLICKEYBYTES]; //Variable declarations
unsigned char sk[crypto_sign_SECRETKEYBYTES]; Variable declarations
crypto_sign_keypair(pk, sk);
NSData *privateKeyData = [NSData dataWithBytes:sk length:crypto_box_SECRETKEYBYTES];
NSData *publicKeyData = [NSData dataWithBytes:pk length:crypto_box_PUBLICKEYBYTES];
NSLog(#"%#",privateKeyData); // target publick key data and secret key data
NSLog(#"%#",publicKeyData);
//Other
NSLog(#"%s\n\n=====\n\n\n%s",pk,sk); //(nullable const void *)bytes
Byte *byte = (Byte *)[publicKeyData bytes];
NSLog(#"%s",byte);

Having trouble in converting data into NSString from NSData

I want to convert NSData into NSString, my code is below.
NSData *data1 = [object valueForKey:#"college_list"];
NSString *myString =[ NSString stringWithCString:[data1 bytes] encoding:NSUTF8StringEncoding];
What is wrong with this code?
If 'data1' do have some thing in it. Try this:
[[NSString alloc] initWithData:data1 encoding:NSUTF8StringEncoding]
May be there is some this wrong with your 'object'. Check its data is valid or issue is in its data.

NSURLResponse Content-Length mismatch size of actual data when running concurrent downloads

I have a UITableView, when a cell is selected, I make a service call to asynchronously download a PDF file from a web service. It works great, until you select multiple cells directly after one-another (individually), then things start going south..
Here's some (stripped down) code to clarify:
Inside MasterViewController.m:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//To uniquely identify this field, I build a simple string using the indexPath.
NSString *key = [[NSString alloc]initWithFormat:#"%d.%d",pIndex.section,pIndex.row];
//Use a pre-populated NSDictionary to specify the file I want from the server.
NSString *reportID = [reportDictionary valueForKey:key];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#/RequestReportWithID",myConnectionObject.ServiceURL]];
NSMutableDictionary *body = [[NSMutableDictionary alloc] initWithObjectsAndKeys:reportID, #"reportID", nil];
NSData *requestData = [NSJSONSerialization dataWithJSONObject:dic options:0 error:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:[NSString stringWithFormat:#"%d", [requestData length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody: requestData];
//Create a new object as delegate to receive the data, also add the key to assist with identification.
ReportDownloader *newReportDownloader = [[ReportDownloader alloc]initWithDelegate:self andKey:key];
NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:newReportDownloader];
if (connection)
{
//Nothing to do here, request was made.
}
}
Inside ReportDownloader.m:
long long expectedReportSize;
NSString *key;
NSData *thisReport;
-(NSObject*)initWithDelegate:(NSObject*)pDelegate andKey:(NSString*)pKey
{
myTypedDelegate = (MasterViewController*)pDelegate;
Key = pKey;
return self;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
expectedReportSize = [response expectedContentLength];
NSLog(#"Key:%#, Expected Size=%lld bytes",Key, [response expectedContentLength]);
thisReport = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[thisReport appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//Here is where things go wrong...
NSLog(#"Key:%#, Actual Size=%ld bytes",Key, (unsigned long)[thisReport length]);
}
The above code works fine for a single report. And on a fast line, it works fine for 3-4 reports, but try to do more than that and the Expected length starts mismatching the Actual length. And I can't understand whyyyyy....
See the output generated by the code above:
(Notice that only the report for indexPath 1.1 was downloaded correctly)
Key:1.0, Expected Size=304006 bytes
Key:1.3, Expected Size=124922 bytes
Key:1.0, Actual Size=369494 bytes
Key:1.3, Actual Size=380030 bytes
Key:1.2, Expected Size=179840 bytes
Key:1.4, Expected Size=377046 bytes
Key:1.2, Actual Size=114376 bytes
Key:1.5, Expected Size=175633 bytes
Key:1.4, Actual Size=180558 bytes
Key:1.5, Actual Size=274549 bytes
Key:1.1, Expected Size=443135 bytes
Key:1.1, Actual Size=443135 bytes
The data corruption is confirmed when trying to open the PDF documents, which fail for all file's who's data size didn't match the expectedContentLength.
I am completely baffled by this behaviour, I'm hoping that I'm making an obvious n00b mistake and that someone here spots it.
The main reason WHY I made the ReportDownloader class was to avoid problems like this one.
Thanks in advance to whoever takes the time to scan my code!
Ok, the solution to this problem can be found here:
https://stackoverflow.com/a/1938395/1014983
This answer by James Wald, although not the question's accepted answer, completely solved all my problems with multiple simultaneous async NSURLConnections.
Let me know if you need some help with the implementation, but it's pretty straight forward.

Binary representation of NSString

I need to someone to send me binary data via NSStream and I will convert it into NSString on my end. What's the binary representation that they need to know (byte size, byte order) in order for me to convert the data successfully back into the same string in NSString?
First get the data and convert it into NSData
Then convert NSData to NSString
NSString* newStr = [[[NSString alloc] initWithData:theData
encoding:NSUTF8StringEncoding] autorelease];
If the data is null-terminated, you should instead use -stringWithUTF8String: to avoid the extra \0 at the end.
NSString* newStr = [NSString stringWithUTF8String:[theData bytes]];
(If you have ARC enabled, remove the -autorelease call.)

Receiving Corrupted Info From Server

On Iphone as well as android I am getting response codes of 200 meaning that I am getting a valid and good response with no errors, but the json that I am receiving has additional characters. I print out the NSData that I receive and it is 580 in length and the NSString, at least when it fails, will have a larger length and print n+ extra characters on the end of the json. I am not sure why this would be but thought I would see if anyone can see what I would be doing incorrectly.
NSString *post = [NSString stringWithFormat:#"referer=%#&username=%#&password=%#", referer, username, password];
NSData *pData = [post dataUsingEncoding: NSUTF8StringEncoding allowLossyConversion:YES];
NSString *pLength = [NSString stringWithFormat:#"%d", [pData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setURL:self.url];
[request setHTTPMethod:#"POST"];
[request setValue:pLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:pData];
[request setTimeoutInterval:30];
NSHTTPURLResponse *response = nil;
NSError *err = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *sData = [NSString stringWithUTF8String:[data bytes]];
I do not receive any errors and every response code that I receive is 200. I have printed out all of these values as well. data length is 580 and sData will vary at times but when it does pass it will be 580 in length, but this can change for different cases. The data will not always be 580 for other users that use the system.
ANSWER:
I solved the problem instead of using
NSString *sData = [NSString stringWithUTF8String:[data bytes]];
You should use
NSString *sData = [[NSString alloc] initWithData: data encoding: NSUTF8String];
This will alloc the correct amount of space based on the NSData object and thus the NSString will never try to access or store more space in that may be behind the last address that should have been accessed.
ANSWER:
I solved the problem instead of using
NSString *sData = [NSString stringWithUTF8String:[data bytes]];
You should use
NSString *sData = [[NSString alloc] initWithData: data encoding: NSUTF8String];
This will alloc the correct amount of space based on the NSData object and thus the NSString will never try to access or store more space in that may be behind the last address that should have been accessed.

Resources