【问题标题】:Porting XOR encryption scheme implemented in PHP移植用 PHP 实现的 XOR 加密方案
【发布时间】:2015-02-22 21:28:05
【问题描述】:

很遗憾,我看不懂 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];
}

【问题讨论】:

  • encrypted 实际上是(替换十六进制):"rDi66Mfqu9y8kvs/3Fc/g+X5N/PtARgPDP7Gk7lLvOxUFNyglxogVA==" 这是有效的 Base64 编码。
  • 顺便说一句,{"date":"01.01.2014 00:00:00","value":5} 不是字符串。

标签: php ios objective-c encryption


【解决方案1】:

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

注意:使用自制加密从来都不是一个好主意,它总是存在缺陷,而是使用标准 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);

输出:

文本:你好异或编码! 编码Base64:ZOHdWKf+cf7vAwpJNfSJ8s8= 预期:ZOHdWKf+cf7vAwpJNfSJ8s8= 解码:你好异或编码!

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-11
      • 2021-01-15
      • 1970-01-01
      • 2018-05-10
      • 1970-01-01
      • 2011-03-15
      • 2013-09-07
      • 1970-01-01
      相关资源
      最近更新 更多