Decrypting RSA with MIHCrypto (OpenSSL-Universal on iOS) - ios

Hi I've got the a Problem with decrypting using MIHCrypto v0.3.2. These are my lines of code:
NSString *encrypted_text = #"BdhFH0sd7e9DExiCd50Ykh4spm2BX126skjJ1o8HHjKsN+J7r9IoI9kbB9AAacEpJsAfyesiJsq5gDBhQtcNbB6l88aSgPrEoVwR9ilzuzVcv1q3J1dxs4uIEMuhzoWT+R8//dD2jDdXPyFsdGWJc10CEizPFKpmy2jWhvU8CVs=";
NSBundle *myBundle = [NSBundle mainBundle];
NSString *privateKeyPath= [myBundle pathForResource:#"rsa_1024_priv" ofType:#"pem"];
NSData *privateKeyData = [[NSFileManager defaultManager] contentsAtPath:privateKeyPath];
MIHRSAPrivateKey *privateKey = [[MIHRSAPrivateKey alloc] initWithData:privateKeyData];
NSError *decryptionError = nil;
// decryption
NSData *encData = [encrypted_text dataUsingEncoding:NSUTF8StringEncoding];
NSData *decryptedEncData = [privateKey decrypt:encData error:&decryptionError];
NSString* decryptedText = [[NSString alloc] initWithData:decryptedEncData encoding:NSUTF8StringEncoding]; // iOS 7+, by iOS Core API
if(decryptionError){
DDLogDebug(#"error: %#",[encryptionError localizedDescription]);
}
DDLogDebug(#"decrypted: %#",decryptedEncData);
The problem is debugged here:
error: OpenSLL internal error! (Code=67522668,Description=error:0406506C:rsa routines:RSA_EAY_PRIVATE_DECRYPT:data greater than mod len)
Do you have any Idea?

I finally found a solution:
Using shorter Blocks of Data!
Background (posted by Hohl - here):
Using RSA with large blocks of data seems to be a common issue. Some
wrappers handle this by splitting the data into smaller blocks and
encrypting every block separately. But since RSA isn't intended to
encrypt large blocks of data this won't be implemented in this wrapper.
(Better combine RSA with something like AES if you need features of
both worlds.)

Related

How can I convert NSData to NSString without encoding to base64?

I'm working on a game in Unity and I currently need to authenticate a apple user and receive some data, which apparently can only be done in native code. I found this code online, which works well, but some of the data is encoded in base64 and I need it decoded. I can try and decode it on the Unity side but it doesn't seem to work and it would be better to receive the raw data so I can work with it as I need.
The code is below:
[localPlayer fetchItemsForIdentityVerificationSignature:
^(NSURL *publicKeyUrl, NSData *signature, NSData *salt, uint64_t timestamp, NSError *error)
{
if (error)
{
NSLog(#"ERROR: %#", error);
OnFailed([[error localizedDescription] UTF8String]);
}
else
{
NSString *signatureb64 = [signature base64EncodedStringWithOptions:0];
NSString *saltb64 = [salt base64EncodedStringWithOptions:0];
NSString *playerId = localPlayer.playerID;
NSString *alias = localPlayer.alias;
NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
OnSucceeded(
[[publicKeyUrl absoluteString] UTF8String],
timestamp,
[signatureb64 UTF8String],
[saltb64 UTF8String],
[playerId UTF8String],
[alias UTF8String],
[bundleId UTF8String]
);
}
}
];
The data I need decoded is the salt and the signature
If I'm not wrong, what I actually need is to convert from NSData to const char * as it is how the data is returned in the callback, instead of NSData to NSString as I wrote in the title, but I thought the title would sound better like that.
I believe what I need is relatively simple but most of my knowledge is in C# for Unity and some web stuff, so I'm a complete potato regarding cpp and apple in native code. Multiple solutions I found online either didn't compile or returned null.
Thanks in advance!

How to encrypt the NSString in ios locally

I am working on the static application that means no webservices. My application contains activation page so that we need to enter text inside that textfield to validate.
if([textfield.text isEqualToString:#"AKS_BI"]) {
//loading home screen
} else {
//show alert
}
For this one, I would like to encrypt the "AKS_BI" in order to hide the string while reverse engineering or Mat testing.
Can you anyone help me on this.
To encrypt:
//for best practise encrypting string length must be >=8
NSString *yourString=#"abcdefghij";
NSString *YourPasswordString = #"123456";//i've took static but you can set it dynamically
NSString *encryptPassword;
//Encrypt
NSData *data = [YourPasswordString dataUsingEncoding: NSASCIIStringEncoding];
NSData *encryptedData = [data AESEncryptWithPassphrase:yourString];
//Encode Base 64
[Base64 initialize];
encryptPassword = [Base64 encode:encryptedData];
For more details you can check here
Hope this helps.
You can use this library https://github.com/RNCryptor/RNCryptor.
However, you will still need to store the encryption key securely. For that I would recommend to split them up and perform some operation on them to combine.
Download AES encryption files from github. Download from here
After adding these downloaded files in your project now compare ,
if ([[AESCrypt encrypt:textfield.text password:[[NSBundle mainBundle] bundleIdentifier]] isEqualToString:ACTIVATION_STRING])
Here, ACTIVATION_STRING = hYjhuOO+GYTUBS05== .... This encrypted string needs to be created with the below syntax and make sure that remove the below syntax from code after generation of encrypted string,
NSString *encryptedData = [AESCrypt encrypt:#"AKS_BI" password: [[NSBundle mainBundle] bundleIdentifier]];
That's it. It simple.

iOS NSURL queuing mechansim for multiple requests from file

I am very new to iOS development, but I would like to make an app that has two table view controllers (columns): both are a row of images that act as links. The first would be a column of YouTube videos and the second a column of websites. I would like to have all these listed in a file file.txt listed like so: V, http://youtube.com/example W, http://example.com
There would be a long list of those, the V meaning its a video (for the video column) and W for the websites. Now, I understand how to being the single file in, but what happens afterwards is my concern. Can I read each line into some sort of queue and then fire the NSURL request for each one consecutively? How can that be done with NSURL? Is there perhaps a better approach?
There are two questions for me:
Is a text file really the best format?
I might suggest a plist or archive (if the file is only going to exist only in your app's bundle and/or documents folder) or JSON (if it's going to live on a server before delivering it to the user) instead of a text file. It will make it easier to parse this file than a text file. For example, consider the following dictionary:
NSDictionary *dictionary = #{#"videos" : #[#"http://youtube.com/abc", #"http://vimeo.com/xyz"],
#"websites": #[#"http://apple.com", #"http://microsoft.com"]};
You can save that to a plist with:
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"files.plist"];
[dictionary writeToFile:plistPath atomically:YES];
You can add that file to your bundle or whatever, and then read it at a future date with:
dictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
You can, alternatively, write that to a JSON file with:
NSError *error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonPath = [documentsPath stringByAppendingPathComponent:#"files.json"];
[data writeToFile:jsonPath atomically:YES];
You can read that JSON file with:
data = [NSData dataWithContentsOfFile:jsonPath];
dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
Either way, you can get the list of videos or web sites like so:
NSArray *videos = dictionary[#"videos"];
NSArray *websites = dictionary[#"websites"];
Now that you have your arrays of videos and websites, the question then is how you then use those URLs.
You could do something like:
for (NSString *urlString in videos) {
NSURL *url = [NSURL URLWithString: urlString];
// now do something with the URL
}
The big question is what is the "do something" logic. Because you're dealing with a lot of URLs, you would want to use a NSOperation based solution, not a GCD solution, because NSOperationQueue lets you control the degree of concurrency. I'd suggest a NSOperation-based networking library like AFNetworking. For example, to download the HTML for your websites:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 4;
for (NSString *urlString in websites)
{
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// convert the `NSData` responseObject to a string, if you want
NSString *string = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
// now do something with it, like saving it in a cache or persistent storage
// I'll just log it
NSLog(#"responseObject string = %#", string);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error = %#", error);
}];
[queue addOperation:operation];
}
Having said that, I'm not sure it makes sense to kick off a ton of network requests. Wouldn't you really prefer to wait until the user taps on one of those cells before retrieving it (and for example, then just open that URL in a UIWebView)? You don't want an app that unnecessarily chews up the user's data plan and battery retrieving stuff that they might not want to retrieve. (Apple has rejected apps that request too much data from a cellular connection.) Or, at the very least, if you want to retrieve stuff up front, only retrieve stuff as you need it (e.g. in cellForRowAtIndexPath), which will retrieve the visible rows, rather than the hundreds of rows that might be in your text/plist/json file.
Frankly, we need a clearer articulation of what you're trying to do, and we might be able to help you with more concise counsel.

Error while encrypting string in staticLibrary

In my application I am using encryption and decryption.
Before entering the string in to local database, I am encrypting that and after fetching the data from database I am decrypting it and using in my application.
It is working fine. I have used encryption/decryption from
link below
At the time of Encrypting:
NSString *myKey=#"any string more than 8 char";
NSData *data ;
NSData *encryptedData;
NSString *encryptPassword,*encryptPasscode;
// 1) Encrypt
data = [password dataUsingEncoding: NSASCIIStringEncoding];
encryptedData = [data AESEncryptWithPassphrase:myKey];
// 2) Encode Base 64
[Base64 initialize];
encryptPassword = [Base64 encode:encryptedData];
At the time of Decrypting :
NSData *decryptedData;
NSData *b64DecData;
field1 = (char *) sqlite3_column_text(selectPasscodeStatement, 0);
NSString *fieldStr1 = [[NSString alloc] initWithUTF8String: field1];
// 3) Decode Base 64
b64DecData = [Base64 decode:fieldStr1];
// 4) Decrypt
decryptedData = [b64DecData AESDecryptWithPassphrase:myKey];
retrivedPasscode = [[NSString alloc] initWithData:decryptedData encoding:NSASCIIStringEncoding];
But I have made staticLibrary of that same project. I am using that staticLibrary in another project. When I run that project, at the time of encrypting it gave me error below
-[NSConcreteMutableData AESEncryptWithPassphrase:]: unrecognized selector sent to instance 0x6a3fe40
You need to make change in the Build Settings of the project which will link the static library with the main project.
Follow these steps:
1)Click on Build Settings tab.
2)Search for "Other Linker Flags".
3)Add '-all_load' flag to it.
4)Build and run the project.
It worked fine for me.
Did you import the category header file:
#import "NSData-AES.h"
I believe there is the AESDecryptWithPassphrase method defined. Without that the app does not know about the method.
Just to clarify - you have to import the category header file to every file where you want to use the capabilities added by that category.

library for iOS to split huge binary files by certain sizes?

I am looking for the library for splitting (divide) a binary file into multiple files.
If there is 20MB size of file named "test.m4v" in iOS temporary folder (NSTemporaryDirectory()),
I would like to split that to
test.m4v.000 (7MB)
test.m4v.001 (7MB)
test.m4v.002 (6MB)
Something like that (It doesn't have to be '7MB', could be 5MB like that)
like command line split command., I don't think we can call this command inside iOS app.
Is there iOS (free/paid) library to do that? I might need to just low level access and write it, but I am too lazy to do that ;)
This should work assuming the file isn't so large that it freaks out at dataWithContentsOfFile:filename. iOS might do caching in the background, but I don't know.
-(NSUInteger)splitFile:(NSString *)filename chunkSize:(NSUInteger)chunkSize {
NSUInteger chunksWritten;
NSFileManager *fm = [[[NSFileManager alloc] init] autorelease];
NSData *fileData = [NSData dataWithContentsOfFile:filename];
NSString *newFileName;
NSRange dataRange;
for (chunksWritten = 0; chunksWritten * chunkSize < [fileData length]; chunksWritten++) {
newFileName = [filename stringByAppendingPathExtension:[NSString stringWithFormat:#"%03d", chunksWritten]];
dataRange = NSMakeRange(chunksWritten * chunkSize, MIN(chunkSize, [fileData length] - chunksWritten * chunkSize));
if (![fm createFileAtPath:newFileName contents:[fileData subdataWithRange:dataRange] attributes:nil]) {
NSLog(#"Error writing chunk #%d", chunksWritten);
break;
}
}
return chunksWritten;
}
The error checking obviously needs to be more robust.

Resources