移植在PHP中实现的XOR加密方案

时间:2014-12-24 21:37:55

标签: php ios objective-c encryption

不幸的是,我无法理解php代码,但我需要将这个php代码转换为Objective-C。 在Objective C中可能是谁知道其他方式进行XOR加密?

我需要这是结果加密:

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代码,我发现:

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! */

我尝试使用此代码,但它不适用于我的示例,因为加密字符串与示例中的不一样(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];
}

2 个答案:

答案 0 :(得分:0)

您尝试翻译的PHP代码未实现您在Objective-C代码中实现的类型的简单XOR编码。它使用一种相当奇怪的方案(基于SHA1)来生成对输入进行异或的非重复焊盘。

您的Objective-C代码的PHP等价物将是:

function strcode($str, $passwd) {
    return $str ^ str_repeat($passwd, ceil(strlen($str) / strlen($passwd)));
}

实现当前PHP代码的等效代码会更困难一些。您可以使用CC_SHA1来计算SHA1哈希值,但请注意它的调用约定比PHP中的约束要快。

答案 1 :(得分:0)

您需要实现创建$gamma的方法。 然后编码或解码创建$ gamma并使用输入xor。

注意:使用自制加密绝不是一个好主意,它总是有缺陷,而是使用标准AES。

由于这是加密,您必须获得应用程序的导出权限,并且使用自行生成的算法可能会相当困难。您将需要美国出口许可,因为正在分发应用程序的是Apple。

这是示例代码,它可能更好,但它可以工作:

@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 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);

输出:

text:          Hello XOR encode!  
encodedBase64: ZOHdWKf+cf7vAwpJNfSJ8s8=  
expected:      ZOHdWKf+cf7vAwpJNfSJ8s8=  
decoded:       Hello XOR encode!