AES Encryption in ios - ios

my iOS app is connected to a web service. App is written in objective-c. Server sending a string that has encrypted using AES encryption using a password string and IV string. I want to decrypt that string in this app side. How can I do it?
Please help me. Thanks
UPDATE
This is how I decrypt my string
NSData *url1Data = [strEncrypted dataUsingEncoding:NSUTF8StringEncoding];
NSData *url1DataDecrypt = [[StringEncryption alloc] decrypt:url1Data key:Hashkey iv:iv];
NSString * decryptedText = [[NSString alloc] initWithData:url1DataDecrypt encoding:NSUTF8StringEncoding];

You need generate Public key certificate & distribute to both side user FBEncrypt Library to decrypt data using AES Algorithm it is secure & Easy to implement FBEncrypt Library.

Related

Trying To Make Sense of RNCryptor

I am working on a project and we need to encrypt some user credentials (username, password, userId, ect.) to pass to our server. We have decided to use AES256 in order to achieve this. Doing some research on this subject it was hard to avoid noticing a project out there, RNCryptor that claims to be an easy-to-use solution to this problem.
So I included the framework into my project and soon realized it was not as straight forward as I thought. I was hoping for a solution to where I could encrypt my credential strings by simply - (1) derive a key that I would like to encrypt my stringed credentials with, (2) pass the key and my string into the appropriate RNCryptor's method, (3) retrieve my encrypted string back from said method.
This would be too good to be true however.
The reality of RNCryptor is that it has methods like this:
[RNEncryptor encryptData:someData
withSettings:kRNCryptorAES256Settings
password:someString
error:&someError];
This is confusing because of the terminology.
WHAT IS PASSWORD?
This is never explained. A password for what? Is this for a user password I want to encrypt, the password key that I want to encrypt with, or the password to login to my computer (sarcasm).
ENCRYPT DATA?
Is this a UTF8 encoded string of what the user credentials that I want to encrypt? That is my best guess but again, not explained in the RNCryptor Github "documentation".
password is used to generate the encryption key, it is an NSString the data is encrypted with. encryptData is the data to encrypt and is an NSData.
Encryption works with data, that an array of 8-bit bytes. You need to convert whatever you have to an NSData. For an NSString there is the method:
NSData *dataToBeEncrypted = [myString dataUsingEncoding:NSUTF8StringEncoding];
and
NSString *myString = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
Additionally it requires an encryption key, RNCryptor takes an NSString and derives an encryption key from it.
There are of course options and while most of these handles internally by RNCryptor there still some available to the developer using it.
There two main versions with more options, you are probably best off using the password version.
One taking a NSString password:
+ (NSData *)encryptData:(NSData *)data withSettings:(RNCryptorSettings)settings password:(NSString *)password error:(NSError **)error;
A second taking an NSData encryption key as well as a NSData authentication key.
+ (NSData *)encryptData:(NSData *)data withSettings:(RNCryptorSettings)settings encryptionKey:(NSData *)encryptionKey HMACKey:(NSData *)HMACKey error:(NSError **)error;
RNCryptor is you best choice, it handles key derivation from a password, a random IV, authentication of the encrypted data and padding.

Importing / Exporting RSA SecKeyRef key using Apple's Security Framework

I'm creating an iPhone Objective-C app that uses secure communication between a server and a client. The protocol I want to follow goes like this:
The client is compiled and distributed with the Server's Public RSA key (hardcoded). Let's call this Kspub. (For Key Server Public)
The client generates an random AES key. Let's call this key Kcaes (for Key Client AES)
The client encrypts Kcaes using Kspub, and produces the encrypted text: Kspub(Kcaes)
The client sends Kspub(Kcaes) to the server.
The server decrypts Kspub(Kcaes) using the server's private key, Kspri. This recovers Kcaes. Now the client and the server both share a common AES key, Kcaes.
To verify this, the server encrypts Kcaes USING Kcaes. This produces encrypted text Kcaes(Kcaes).
The server sends Kcaes(Kcaes) to the client.
The client decrypts Kcaes(Kcaes) using the Kcaes key. This produces Kcaes. If this matches the original Kcaes, then the client knows it has established a secure connection.
The client and server can now securely exchange information using symmetrical key Kcaes.
I have already implemented server-side and client-side key generation, encryption, and decryption methods. Currently, keypairs generated on the iPhone are being stored in it's keychain. Here's the issue:
I cannot seem to find a method in Apple's Keychain or Security API to import a Public RSA key from a text file. How can I import a key through a text file and store it in a SecKeyRef object?
Thanks!
You do this via SecItemAdd, passing:
A dictionary containing an item class key-value pair (Keychain Item Class Keys and Values) and optional attribute key-value pairs (Attribute Item Keys and Values) specifying the item's attribute values.
OSStatus err = SecItemAdd((CFDictionaryRef)
[NSDictionary dictionaryWithObjectsAndKeys:
(id)kSecClassKey, kSecClass,
kSecAttrKeyTypeRSA, kSecAttrKeyType,
keyTagUTF8, kSecAttrApplicationTag,
kSecAttrKeyClassPrivate, kSecAttrKeyClass,
keyData, kSecValueData,
nil],
NULL);
Ensure that the attributes to store and retrieve match exactly.
SecKeyCreateWithData will accept RSA data in PKCS#1 as well as the x509 public key format.
Because the question mentions a text as opposed to binary file I'll assume the public key is in the standard PEM format. First you'd strip the PEM headers and new lines:
NSMutableString *pemString = [textFileString mutableCopy];
[pemString replaceOccurrencesOfString:#"-----BEGIN PUBLIC KEY-----" withString:#"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [pemString length])];
[pemString replaceOccurrencesOfString:#"-----END PUBLIC KEY-----" withString:#"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [pemString length])];
[pemString replaceOccurrencesOfString:#"\n" withString:#"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [pemString length])];
Now you're left with a Base64 string which you can decode into binary data. I want to point out that Apple's native Base64 methods are not tolerant of padding issues and other standards.
CFDataRef data = (__bridge CFDataRef) [NSData dataWithBase64EncodedString... // Your preferred base64 method here
Now you can get the SecKeyRef via SecKeyCreateWithData.
if (data)
{
CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (dictionary)
{
CFDictionarySetValue(dictionary, kSecAttrKeyClass, kSecAttrKeyClassPublic);
CFDictionarySetValue(dictionary, kSecAttrIsPermanent, kCFBooleanFalse);
CFDictionarySetValue(dictionary, kSecAttrKeyType, kSecAttrKeyTypeRSA);
CFErrorRef error = NULL;
SecKeyRef publicKey = SecKeyCreateWithData(data, dictionary, &error);
if (publicKey)
{
if (error)
{
CFShow(error);
CFRelease(error);
}
//...
CFRelease(publicKey);
}
CFRelease(dictionary);
}
}
From here you can either keep the reference around, or decide to save it in the keychain via SecItemAdd etc.

ios usaepay magstripe credit card data, send for processing

In my application I use online payment, for that i used PaySabar device (audio jack device) which reads magstrip data on credit card swipe.
I got credit data in encrypted format, all track1, track2 data are correct and perfect, but how to i send that data to USAePAY server. Please help.
I believe USAePay requires the encrypted data to be:
Encrypted with their public key
Formatted in a specific manner
Passed in magstripe or credit card number field
Because you are using their PaySaber hardware, see below for step 3.
USAePay Wiki - End To End Encryption:
If you are using idynamo library, here is what you need to do:
NSString *responseString = [mtSCRALib getResponseData];
NSData *responseData = [responseString dataUsingEncoding:NSASCIIStringEncoding];
NSString *encodedString = [NSString stringWithFormat:#"enc://%#", [^] [responseData base64Encoding]];
and then send encodedString to the gateway as MagStripe.
You will need to integrate your application with one of their transaction interfaces. You will also need a developer account for testing transaction responses.
They have a wide array of different integration solutions and source code examples to use, including an iOS library.
http://wiki.usaepay.com/developer/Support

Instagram Signed API Call from iOS

To make the Signed API calls for Instagram post methods to Follow user, Like user's image etc. Users Have limit of 20 Follow per Hour. But if we make Signed API call then user can make 60 Follow per hour. But My question is how to make Signed API call. ?
I tried this method as desribed on Instagram http://instagram.com/developer/restrict-api-requests/ and Make Enforced header enable .and Sent X-Insta-Forwarded-For header field with valid Id. But still after 20 follow it is showing Limit error. Can anyone please help me to how to make Signed API call .
Thanks in advance.
After searching for the things I resolved my issue by this, By making my app signed app:
to make Signed API call for Instagram user need to check both the checkbox in their insta App. under manage clients. and Have to follow The Implicit OAuth Grant flow.
For All Follow/Like post type request user need to add one header:
of Type as
X-Insta-Forwarded-For -> [IP information]|[Signature]
IP should be it the client's remote IP as detected by the your app's load balancer;
Signature is , apply an HMAC with SHA256, and append the hex representation of the signature there . On the IP address as data using your clientSecret as key.
Then join IP info and Signature using pipe | and set that as the value of the header field.
I had used the following code to generate Signature:
-(NSString *)signWithKey:(NSString *)key usingData:(NSString *)data
{
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
return [[HMAC.description stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]] stringByReplacingOccurrencesOfString:#" " withString:#""];
}
-(NSString*)getheaderData
{
NSString *ipString = [self fetchMyIP];
NSString *signature = [self signWithKey:kClientSecret usingData:ipString];
}
To set header in iOS: [request setValue:[self getheaderData] forHTTPHeaderField:#"X-Insta-Forwarded-For"];
So the API call will be sent as the Signed API call.

Making AWS Product Advertising API Request iOS

Today i have been unable to make a request for an "ItemSearch" request for the product advertising api for aws.
First off, this was working Monday Feburary 24th and now March 1st it does not work. I don't know if there was any updates that may have changed the way AWS works. I couldn't find anything when searching.
My first error is: "Request has expired. Timestamp date is 140301235753Z" this means that the time i enter for the request "140301235753Z" is 15 minutes out of range of what AWS has stored for the UTC time. I do a bit of research and end up changing the code below.
NSDateFormatter *UTCFormatter = [[NSDateFormatter alloc] init];
UTCFormatter.dateFormat = #"yyMMddHHmmss'Z'";
UTCFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:#"UTC"];
NSString *timeStamp = [UTCFormatter stringFromDate:[NSDate date]];
i changed the #"yyMMddHHmmss'Z'" to #"yyyy-MM-dd'T'HH:mm:ss'Z'"
Re-running the request again i came across this error: "The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method." this means that the signature portion of the API call that i calculate is wrong when comparing the one AWS calculates when it receives my request.
I have used this link Amazon Signature Examples as a reference to check my code below.
// create HMAC with SHA256
const char *cKey = [secretKey cStringUsingEncoding:NSUTF8StringEncoding];
const char *cData = [canonicalString cStringUsingEncoding:NSUTF8StringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *hashData = [NSData dataWithBytes:cHMAC length:CC_SHA256_DIGEST_LENGTH];
NSString *signature = [[DTBase64Coding stringByEncodingData:hashData] stringByURLEncoding];
I don't see an error with my code. I have looked, via google, for an application that may be able to create the string i desire in order to test if my signature is correct, but AWS didn't seem to have anything (that i could find, i could just be a bad googler).
My secret key for the AWS had a "/" character in it. I thought this might be messing with the algorithms for calculating the HMAC. So i created new secret keys until amazon generated me one with out odd characters and tested it. It did not work....
Ultimately what i am trying to make is an AWS Product Advertising API Request using this information
NSString *verb = #"GET";
NSString *hostName = #"webservices.amazon.com";
NSString *path = #"/onca/xml";
NSDictionary *params = #{
#"Service": #"AWSECommerceService",
#"AWSAccessKeyId": accessKey,
#"Operation": #"ItemSearch",
#"ResponseGroup": #"Large",
#"SearchIndex": #"Books",
#"Title": bookTitle,
#"AssociateTag" : trackingID
};
I have substituted sensitive/dynamic information with variables.
I have searched through the documentation PDFs at AWS Product Advertising Documentation and can't seem to figure out my problem.
The most baffling part is that my code was working 6 days ago and i have changed nothing.
I've had a similar experience with another third party API. Apparently my request was being redirected and I had to resign my request.
Be sure to sign your request in this nsurlrequest delegate method:
- (NSURLRequest *)connection: (NSURLConnection *)inConnection
willSendRequest: (NSURLRequest *)inRequest
redirectResponse: (NSURLResponse *)inRedirectResponse;
I made a noob mistake and commented out the code that encoded the body parameters. After uncommenting it and setting the values it all worked fine. So make sure you encode your parameters.

Resources