问题
As many of us know, there's been a recent situation with Apple where hackers are able to get any In-App Purchase for free. Apple recently released this document describing how to patch it, but I'm a bit confused on step #4 and would appreciate any help.
The first steps are to download their patch .h and .m, include it in your project, and link it against the Security framework. Okay, good, got it. Then Apple says:
4. Provide a base64 encoder, a base64 decoder, and the action to perform when validation succeeds.
What exactly does the part about the encoders mean I should do? (The action to perform when validation succeeds is clear to me.) I see the functions named base64_encode
and base64_decode
in the class, certainly. But what is it asking for? Is this like a special PIN number that only I know, to prevent hacking? I'm not sure what to do here. I get the overall concepts of encoding and decoding, of course, but not the programmatic specifics of how to generate one properly in this situation.
The code as Apple writes it, if this helps any:
- (NSString *)encodeBase64:(const uint8_t *)input length:(NSInteger)length
{
#warning Replace this method.
return nil;
}
- (NSString *)decodeBase64:(NSString *)input length:(NSInteger *)length
{
#warning Replace this method.
return nil;
}
#warning Implement this function.
char* base64_encode(const void* buf, size_t size)
{ return NULL; }
#warning Implement this function.
void * base64_decode(const char* s, size_t * data_len)
{ return NULL; }
I'm also perplexed that there are 2 encode and 2 decode functions. I get that there's a pair that returns NSString*
s, but why does the second pair return a char*
and a void*
? What are these functions expected to return? I really don't get it.
回答1:
Sounds like they want a general-purpose base64 encoder. Try some of the code here:
http://cocoadev.com/wiki/BaseSixtyFour
(disclaimer: I have not tested any of this)
Here's a second one that's rather easier to read: http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html
回答2:
Please have a look at a solution presented: here, posted by unknown author.
which contains the following code, which I tested and works for me:
// single base64 character conversion
static int POS(char c)
{
if (c>='A' && c<='Z') return c - 'A';
if (c>='a' && c<='z') return c - 'a' + 26;
if (c>='0' && c<='9') return c - '0' + 52;
if (c == '+') return 62;
if (c == '/') return 63;
if (c == '=') return -1;
[NSException raise:@"invalid BASE64 encoding" format:@"Invalid BASE64 encoding"];
return 0;
}
- (NSString *)encodeBase64:(const uint8_t *)input length:(NSInteger)length
{
return [NSString stringWithUTF8String:base64_encode(input, (size_t)length)];
}
- (NSString *)decodeBase64:(NSString *)input length:(NSInteger *)length
{
size_t retLen;
uint8_t *retStr = base64_decode([input UTF8String], &retLen);
if (length)
*length = (NSInteger)retLen;
NSString *st = [[[NSString alloc] initWithBytes:retStr
length:retLen
encoding:NSUTF8StringEncoding] autorelease];
free(retStr); // If base64_decode returns dynamically allocated memory
return st;
}
char* base64_encode(const void* buf, size_t size)
{
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char* str = (char*) malloc((size+3)*4/3 + 1);
char* p = str;
unsigned char* q = (unsigned char*) buf;
size_t i = 0;
while(i < size) {
int c = q[i++];
c *= 256;
if (i < size) c += q[i];
i++;
c *= 256;
if (i < size) c += q[i];
i++;
*p++ = base64[(c & 0x00fc0000) >> 18];
*p++ = base64[(c & 0x0003f000) >> 12];
if (i > size + 1)
*p++ = '=';
else
*p++ = base64[(c & 0x00000fc0) >> 6];
if (i > size)
*p++ = '=';
else
*p++ = base64[c & 0x0000003f];
}
*p = 0;
return str;
}
void* base64_decode(const char* s, size_t* data_len_ptr)
{
size_t len = strlen(s);
if (len % 4)
[NSException raise:@"Invalid input in base64_decode" format:@"%d is an invalid length for an input string for BASE64 decoding", len];
unsigned char* data = (unsigned char*) malloc(len/4*3);
int n[4];
unsigned char* q = (unsigned char*) data;
for(const char*p=s; *p; )
{
n[0] = POS(*p++);
n[1] = POS(*p++);
n[2] = POS(*p++);
n[3] = POS(*p++);
if (n[0]==-1 || n[1]==-1)
[NSException raise:@"Invalid input in base64_decode" format:@"Invalid BASE64 encoding"];
if (n[2]==-1 && n[3]!=-1)
[NSException raise:@"Invalid input in base64_decode" format:@"Invalid BASE64 encoding"];
q[0] = (n[0] << 2) + (n[1] >> 4);
if (n[2] != -1) q[1] = ((n[1] & 15) << 4) + (n[2] >> 2);
if (n[3] != -1) q[2] = ((n[2] & 3) << 6) + n[3];
q += 3;
}
// make sure that data_len_ptr is not null
if (!data_len_ptr)
[NSException raise:@"Invalid input in base64_decode" format:@"Invalid destination for output string length"];
*data_len_ptr = q-data - (n[2]==-1) - (n[3]==-1);
return data;
}
来源:https://stackoverflow.com/questions/11612897/patching-in-app-purchase-hack-stuck-on-fourth-step