encrypted data return nil string - iphone

I am using Rijndael Encryption Algorithm when I am going to encrypt it, it encrypted in NSData. I want that encrypted NSdata into NSString. I tried to convert it into string but it return nil. Have anyone any solutions to get into string.
I am doing like this
NSString *passphrase = #"super-secret";
NSStringEncoding myEncoding = NSUTF8StringEncoding;
NSString *alphaPlain = #"This is a encryption test.";
NSData *alphaDataPlain = [alphaPlain dataUsingEncoding:myEncoding];
NSLog(#" SimpleText value : %#",alphaPlain);
NSData *alphaDataCypher = [alphaDataPlain AESEncryptWithPassphrase:passphrase];
NSString *alphaStringCypher = [[NSString alloc] initWithData:alphaDataCypher encoding:myEncoding];
NSLog(#" Encrypted value : %#",alphaStringCypher);
It returns nil value.
Thanks

The encrypted data is no longer a UTF8 string, it's just some sequence of bytes, so decoding it as UTF8 fails.
What do you want to do with the string? If it's just for logging/debugging purposes, you could use [myData description] to get a hex string (with some extra whitespace for better readability). If you need this to transfer the data in a context where you need a textual representation, converting it to Base64 would be a good idea, see this answer for an easy way to do that.

Related

Swift 3, in Poloniex trade Api get - "error": Invalid command

My code:
func testApi() {
Alamofire.request("https://www.poloniex.com/tradingApi", withMethod: .post, parameters: ["command":"returnDepositAddresses","nonce":nonce()], encoding: .json, headers: ["Key":apiKey,"Sign":newSecret]).responseJSON() { (dataBack) in
print(dataBack)
}
}
func nonce() -> Int {
let date = "\(NSDate().timeIntervalSince1970)"
let UnixInt = Double(date)!
return Int(UnixInt)
}
And I get it:
SUCCESS: {
error = "Invalid command.";}
I can't find any info about poloniex api with Swift or Objective C...
So if somebody can help - I'll be very grateful
Here is an example of how to form your NSURLRequest for poloniex.com.
Imagine that your:
API Key = #"apikey"
Secret = #"secret"
nonce = #"1"
Starting with the simplest things:
NSMutableURLRequest *theURLRequest = [NSMutableURLRequest new];
theURLRequest.URL = [NSURL URLWithString:#"https://poloniex.com/tradingApi"];
theURLRequest.HTTPMethod = #"POST";
NSString *theBodyString = #"command=returnBalances&nonce=1";
theURLRequest.HTTPBody = [theBodyString dataUsingEncoding:NSUTF8StringEncoding];
[theURLRequest setValue:#"apikey" forHTTPHeaderField:#"Key"];
And now the hardest bit...
As to me, Poloniex documentation wasn't very clear on what they want under the "Sign" header field value, but basically they want you to pass a string, which should be a result of HMAC SHA512 encryption algorithm applied to both theBodyString and Secret (which in our example is simply #"secret").
Here is the function which would return you the HMAC SHA512 NSData:
#import <CommonCrypto/CommonHMAC.h>
NSData * getHMACSHA512FromSecretKeyStringAndBodyString(NSString *theSecretKeyString, NSString *theBodyString)
{
const char *cSecret = [theSecretKeyString cStringUsingEncoding:NSUTF8StringEncoding];
const char *cBody = [theBodyString cStringUsingEncoding:NSUTF8StringEncoding];
unsigned char cHMAC[CC_SHA512_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA512, cSecret, strlen(cSecret), cBody, strlen(cBody), cHMAC);
return [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
}
So, running:
NSData *theData = getHMACSHA512FromSecretKeyStringAndBodyString(#"secret", #"command=returnBalances&nonce=1");
NSString *theString = [NSString stringWithFormat:#"%#", theData];
Would give us almost what we wanted.
Our result is equal to:
<c288f881 a6808d0e 78827ec6 ca9d6b9c 34ec1667 07716303 0d6d7abb 2b225456 31176f52 8347ab0f d6671ec5 3aec1f7d 3b6de8b8 e3ccc23d e62fd594 52d70db5>
While what we actually want (as per http://www.freeformatter.com/hmac-generator.html) is:
c288f881a6808d0e78827ec6ca9d6b9c34ec1667077163030d6d7abb2b22545631176f528347ab0fd6671ec53aec1f7d3b6de8b8e3ccc23de62fd59452d70db5
So, basically, just remove the <, > and symbols from your string;
theString = [theString stringByReplacingOccurrencesOfString:#"<" withString:#""];
theString = [theString stringByReplacingOccurrencesOfString:#">" withString:#""];
theString = [theString stringByReplacingOccurrencesOfString:#" " withString:#""];
[theURLRequest setValue:theString forHTTPHeaderField:#"Sign"];
Your theURLRequest is now ready and should succeed getting the tradingApi of poloniex.com.
Actually it's neither Swift nor iOS issue.
It's because you are accessing Trading API methods, and they may require some more additional parameters (except of nonce) in your POST request:
Check this:
All calls to the trading API are sent via HTTP POST to
https://poloniex.com/tradingApi and must contain the following
headers:
Key - Your API key. Sign - The query's POST data signed by your key's
"secret" according to the HMAC-SHA512 method. Additionally, all
queries must include a "nonce" POST parameter. The nonce parameter is
an integer which must always be greater than the previous nonce used.
Thus:
All responses from the trading API are in JSON format. In the event of
an error, the response will always be of the following format:
{"error":""}
https://temp.poloniex.com/support/api/

Decode URL into JSON

I am getting the following response
param=%7B%22paymentMode%22:%22%22,%22transactionId%22:%2231674%22,%22pgRespCode%22:%223%22,%22TxMsg%22:%22Canceled%20by%20user%22,%22authIdCode%22:%22%22,%22currency%22:%22INR%22,%22amount%22:%221.00%22,%22addressStreet1%22:%22Sesame%20street%22,%22addressStreet2%22:%22%22,%22isCOD%22:%22%22,%22loadStatus%22:%22fail%22,%22TxId%22:%22123456%22,%22addressCountry%22:%22India%22,%22firstName%22:%22Ankur%22,%22TxGateway%22:%22%22,%22signature%22:%2245558eb93513aa7a4f2fba24e0ba577b26eb5f40%22,%22addressState%22:%22Pune%22,%22lastName%22:%22Arya%22,%22addressCity%22:%22%22,%22TxRefNo%22:%22CTX1307151506338704178%22,%22loadAmount%22:%221.00%20INR%22,%22pgTxnNo%22:%22CTX1307151506338704178%22,%22TxStatus%22:%22CANCELED%22,%22email%22:%22daredevil.suyash#gmail.com%22,%22issuerRefNo%22:%22%22,%22mobileNo%22:%229900414420%22,%22addressZip%22:%22411045%22%7D
how can I decode it into the following
param={"paymentMode":"","transactionId":"31674","pgRespCode":"3","TxMsg":"Canceled by user","authIdCode":"","currency":"INR","amount":"1.00","addressStreet1":"Sesame street","addressStreet2":"","isCOD":"","loadStatus":"fail","TxId":"123456","addressCountry":"India","firstName":"Ankur","TxGateway":"","signature":"45558eb93513aa7a4f2fba24e0ba577b26eb5f40","addressState":"Pune","lastName":"Arya","addressCity":"","TxRefNo":"CTX1307151506338704178","loadAmount":"1.00 INR","pgTxnNo":"CTX1307151506338704178","TxStatus":"CANCELED","email":"daredevil.suyash#gmail.com","issuerRefNo":"","mobileNo":"9900414420","addressZip":"411045"}
You can try this method stringByReplacingPercentEscapesUsingEncoding:NSStringEncodingConversionAllowLossy]
Taken from this question urldecode in objective-c
//
NSString *param=#"%7B%22paymentMode%22:%22%22,%22transactionId%22:%2231674%22,%22pgRespCode%22:%223%22,%22TxMsg%22:%22Canceled%20by%20user%22,%22authIdCode%22:%22%22,%22currency%22:%22INR%22,%22amount%22:%221.00%22,%22addressStreet1%22:%22Sesame%20street%22,%22addressStreet2%22:%22%22,%22isCOD%22:%22%22,%22loadStatus%22:%22fail%22,%22TxId%22:%22123456%22,%22addressCountry%22:%22India%22,%22firstName%22:%22Ankur%22,%22TxGateway%22:%22%22,%22signature%22:%2245558eb93513aa7a4f2fba24e0ba577b26eb5f40%22,%22addressState%22:%22Pune%22,%22lastName%22:%22Arya%22,%22addressCity%22:%22%22,%22TxRefNo%22:%22CTX1307151506338704178%22,%22loadAmount%22:%221.00%20INR%22,%22pgTxnNo%22:%22CTX1307151506338704178%22,%22TxStatus%22:%22CANCELED%22,%22email%22:%22daredevil.suyash#gmail.com%22,%22issuerRefNo%22:%22%22,%22mobileNo%22:%229900414420%22,%22addressZip%22:%22411045%22%7D";
NSString *newParam = [param stringByReplacingPercentEscapesUsingEncoding:NSStringEncodingConversionAllowLossy];
NSLog(#"%#",newParam);
Do string replacement stuff with that to get it into a more readable form.
string = [string stringByReplacingOccurrencesOfString: #"%%22" withString:#"\""];
string = [string stringByReplacingOccurrencesOfString: #"%%7B" withString:#"{"];
string = [string stringByReplacingOccurrencesOfString: #"%%7D" withString:#"}"];
And so on, until you get it into something you want.
You are basically replacing the unicode representation of the character into the actual readable character

How to convert ISO-8859-1encoded string into UTF-8 in Objective C

Does anyone know How to convert ISO-8859-1 encoded string into UTF-8 string or into NSString in Objective C ?
thanks.
Say you have your ISO-8859-1 encoded string in a varaible isoString of type const char*, then you can create an NSString instance like this:
NSString* str = [[NSString alloc]
initWithCString: isoString encoding: NSISOLatin1StringEncoding];
Note: Latin-1 and ISO-8859-1 encoding are the same.
With the following code, you can convert it to a UTF-8 encoded C string if needed:
const char* utf8String = [str UTF8String];
Or in one line:
NSString yourFinalString = [NSString stringWithCString:[yourOriginalString cStringUsingEncoding:NSISOLatin1StringEncoding] encoding:NSUTF8StringEncoding];

Convert response string possibly to utf16

Hello
I am getting a response string from server this string:Kav\u00e1la.
After a search on google this "\u00e1" is UTF16.
I am trying to convert it using this:
NSString *myJson = [responseString stringByReplacingPercentEscapesUsingEncoding:NSUTF16StringEncoding];
but nothing. Its the same
"\u00e1" is the character "รก" (lowercase a-acute).

iOS Development: How can I encapsulate a string in an NSData object?

I'm building a multiplayer game on the iPhone and I need to send string data to the other players in the game. To do that, I need to encapsulate my NSString* string data in an NSData object somehow. Here's an example of how my code is structured...
typedef struct
{
PACKETTYPE packetType;
??? stringToSend; //<---not sure how to store this
} StringPacket;
StringPacket msg;
msg.packetType = STRING_PACKET;
msg.stringToSend = ... // <---not sure what to do here
NSData *packet = [NSData dataWithBytes:&msg length:sizeof(StringPacket)];
So my question is, if StringPacket is a struct defined in my header, what type should the stringToSend property be so that I can easily call the dataWithBytes method of NSData to encapsulate the packet data in an NSData object?
Thanks for your wisdom!
At first, you should convert your NSString to UTF8 representation via [NSString UTF8String].
After that, i'd recommend to store in packet string length, and after that - the string characters themself. All that can be done via appending NSData, created from char* via [NSData dataWithBytes:]
NSMutableData packet = [[NSMutableData alloc] init];
[packet appendBytes:&msg.packetType, sizeof(msg.packetType)];
char *str = [yourString UTF8String];
int len = strlen(str);
[packet appendBytes:(void*)&len, sizeof(len)];
[packet appendBytes:(void*)str, len];
To parse packet back, you should do:
NSData packet; // your packet
[packet getBytes:(void*)&packet.msg range:NSMakeRange(0, sizeof(packet.msg))];
int len;
[packet getBytes:(void*)&len range:NSMakeRange(sizeof(packet.msg), sizeof(len)];
NSData *strData = [packet subdataWithRange:NSMakeRange(sizeof(packet.msg) + sizeof(len)), packet.length];
NSString *str = [[NSString alloc] initWithData:strData encoding:UTF8Encoding];
There can be some mistakes since i'm writing from memory, but I think you'll get the idea.
If your strings have a maximum length, it's rather easy and can be done efficiently. So, assuming your strings max length for these packets is 255 and you've decided to use UTF-8 to encode your strings (both sides need to agree which encoding they're using), you could do it like this:
typedef struct
{
PACKETTYPE packetType;
uint8_t stringToSend[256]; // UTF8 string with max encoded length of 255 bytes
} StringPacket;
StringPacket msg;
msg.packetType = STRING_PACKET;
[theString getCString:msg.stringToSend maxLength:256 encoding:NSUTF8StringEncoding];
NSData *packet = [NSData dataWithBytes:&msg length:sizeof(StringPacket)];
Now you will have a proper C string in your packet that is at most 255 bytes of string data and the null terminator. Note, if your string can't be encoded to UTF8 in the size you gave it, the method will return NO, so your real code should actually check for that and handle it.
If you can't have a size limit, you can basically do the same thing, but you have to deal with dynamically allocating the memory, copying the bytes, creating the data and properly freeing the memory at the right time, so it becomes much more involved but it's the same basic idea. See also the method -getBytes:maxLength:usedLength:encoding:options:range:remainingRange: on NSString, it can be very useful in generating these messages where the string size is dynamic and totally unknown.
For the most simple case, however, the code above should get the job done.