Unfortunately, I can't understand php code, but I need converted this php code to Objective-C. May be who know others way for XOR encrypt in Objective C?
I need this is result encryption:
key: kbyz5eH64z
string: {"date":"01.01.2014 00:00:00","value":5}
encrypted: rDi66Mfqu9y8kvs%2F3Fc%2Fg%2BX5N%2FPtARgPDP7Gk7lLvOxUFNyglxogVA%3D%3D
decrypted: {"date":"01'�Mi�����q�=���e� #~�E�����i�11
php code, that I found:
function strcode($str, $passw="")
{
$salt = "Dn8*#2n!9j";
$len = strlen($str);
$gamma = '';
$n = $len>100 ? 8 : 2;
while( strlen($gamma)<$len )
{
$gamma .= substr(pack('H*', sha1($passw.$gamma.$salt)), 0, $n);
}
return $str^$gamma;
}
$txt = "Hello XOR encode!";
$txt = base64_encode(strcode($txt, 'mypassword'));
echo $txt;
/* result - ZOHdWKf+cf7vAwpJNfSJ8s8= */
$txt = "ZOHdWKf+cf7vAwpJNfSJ8s8=";
$txt = strcode(base64_decode($txt), 'mypassword');
echo $txt;
/* result - Hello XOR encode! */
I'm tried use this code, but it doesn't work for my example, because encrypted string not same like in example (rDi66Mfqu9y8kvs%2F3Fc%2Fg%2BX5N%2FPtARgPDP7Gk7lLvOxUFNyglxogVA%3D%3D):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"document" ofType:@"json"];
NSData *content = [[NSData alloc] initWithContentsOfFile:filePath];
NSString* jsonString = [[NSString alloc] initWithData:content encoding:NSUTF8StringEncoding];
NSLog(@"Input string:%@", jsonString);
NSString *obfuscatedStr = [[self obfuscate:jsonString withKey:@"kbyz5eH64z"] base64EncodedStringWithOptions:0];
NSLog(@"Obfuscated string:%@", obfuscatedStr);
return YES;
}
- (NSData *)obfuscate:(NSString *)string withKey:(NSString *)key
{
// Create data object from the string
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
// Get pointer to data to obfuscate
char *dataPtr = (char *) [data bytes];
// Get pointer to key data
char *keyData = (char *) [[key dataUsingEncoding:NSUTF8StringEncoding] bytes];
// Points to each char in sequence in the key
char *keyPtr = keyData;
int keyIndex = 0;
// For each character in data, xor with current value in key
for (int x = 0; x < [data length]; x++)
{
// Replace current character in data with
// current character xor'd with current key value.
// Bump each pointer to the next character
*dataPtr = *dataPtr ^ *keyPtr;
dataPtr++;
keyPtr++;
// If at end of key data, reset count and
// set key pointer back to start of key value
if (++keyIndex == [key length])
keyIndex = 0, keyPtr = keyData;
}
return [[NSData alloc] initWithData:data];
}
You need to implement the method that creates $gamma
. Then to encode or decode create $gamma and xor it with the input.
Note: using home-build encryption is never a good idea, it always suffers from flaws, instead use standard AES.
Since this is encryption you will have to obtain export permission for an app and that will probably be rather hard with a home-grown algorithm. You will need U.S. export permission since it is Apple who is distributing the app.
Here is example code, it could be better but it works:
@interface Test : NSObject
- (NSData *)strcodeData:(NSData *)data password:(NSString *)password;
@end
@implementation Test
- (NSData *)strcodeData:(NSData *)data password:(NSString *)password {
NSString *gamma = [self gammaWithPassword:password length:data.length];
NSData *gammaData = [gamma dataUsingEncoding:NSMacOSRomanStringEncoding];
NSData *encryptedData = [self xorData:data withString:gammaData];
return encryptedData;
}
- (NSString *)gammaWithPassword:(NSString *)password length:(unsigned long)length {
NSString *salt = @"Dn8*#2n!9j";
NSMutableString *gamma = [NSMutableString new];
int chunkSize = length>100 ? 8 : 2;
NSMutableString *shaFodder = [NSMutableString new];
while( gamma.length < length) {
shaFodder = [NSMutableString stringWithFormat:@"%@%@%@", password, gamma, salt];
NSString *shaStringOut = [self sha1WithString:shaFodder];
[gamma appendString:[shaStringOut substringToIndex:chunkSize]];
}
return gamma;
}
- (NSData *)xorData:(NSData *)d1 withString:(NSData *)d2 {
if (d2.length < d1.length) {
return nil;
}
NSMutableData *dm1 = [d1 mutableCopy];
uint8_t *b1 = dm1.mutableBytes;
const uint8_t *b2 = d2.bytes;
for (int i=0; i<d1.length; i++) {
b1[i] ^= b2[i];
}
return dm1;
}
- (NSString *)sha1WithString:(NSString *)string {
NSData *shaDataIn = [string dataUsingEncoding:NSMacOSRomanStringEncoding];
NSData *shaDataOut = [self doSha1:shaDataIn];
NSString *shaStringOut = [[NSString alloc] initWithData:shaDataOut encoding:NSMacOSRomanStringEncoding];
return shaStringOut;
}
- (NSData *)doSha1:(NSData *)dataIn
{
NSMutableData *macOut = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH];
CC_SHA1( dataIn.bytes,
(const uint8_t)dataIn.length,
macOut.mutableBytes);
return macOut;
}
@end
Test:
Test *test = [Test new];
// Note: NSMacOSRomanStringEncoding is used because it is a true 8-bit encoding
NSString *password = @"mypassword";
NSString *text = @"Hello XOR encode!";
NSLog(@"text: %@", text);
// encode
NSData *data = [text dataUsingEncoding:NSMacOSRomanStringEncoding];
NSData *encodedData = [test strcodeData:data password:(NSString *)password];
NSString *encodedBase64 = [encodedData base64EncodedStringWithOptions:0];
NSLog(@"encodedBase64: %@", encodedBase64);
NSLog(@"expected: ZOHdWKf+cf7vAwpJNfSJ8s8=");
// decode
NSData *encodedEncryptedData = [[NSData alloc] initWithBase64EncodedString:encodedBase64 options:0];
NSData *encryptedData = [test strcodeData:encodedEncryptedData password:password];
NSString *decoded = [[NSString alloc] initWithData:encryptedData encoding:NSMacOSRomanStringEncoding];
NSLog(@"decoded: %@", decoded);
Output:
text: Hello XOR encode! encodedBase64: ZOHdWKf+cf7vAwpJNfSJ8s8= expected: ZOHdWKf+cf7vAwpJNfSJ8s8= decoded: Hello XOR encode!
The PHP code you are trying to translate does not implement simple XOR encoding of the type that you've implemented in your Objective-C code. It is using a rather odd scheme (based on SHA1) for generating a non-repeating pad to XOR against the input.
The PHP equivalent of your Objective-C code would be simply:
function strcode($str, $passwd) {
return $str ^ str_repeat($passwd, ceil(strlen($str) / strlen($passwd)));
}
Implementing an equivalent to your current PHP code will be somewhat more difficult. You can use CC_SHA1
to calculate SHA1 hashes, but note that its calling convention is a little hairier than the one in PHP.