游戏关卡文件的加密策略

凡事有个意图,对游戏关卡文件进行加密的主要目的就是防止被别人二次山寨

当然,仅仅根据游戏关卡文件就山寨出整个游戏来是不可能的事情,

但是游戏关卡文件的结构还是能够透露出相当多的信息,

为防万一,同时也为了让自己在软件安全方面练练手,我选择对游戏关卡文件加密。

次非空穴来风,因为我自己就干过不少类似的事情,看哪个app 做的很好,

便会将 app  的内容导出到电脑里面,分析其所用的素材和框架,使用到了那些技术等等。

所以,这是相当有必要的,你不能假设其他人都是sb,

你得充分去实践怀疑论,尽最大可能去维护自己应有的权益。

ok,闲话不多说,进入正题:

对游戏资源文件的保护我发现以下那么几种方案:

1。将资源文件的2进制数据弄进代码里面,之前我有参照别人提出的这个思路写过一个小工具,

能够将资源文件转化为头文件。这份头文件到时候会无缝契合到程序里面去,性能不知道怎么样,

但是安全性多少还是有些的——对逆向不是很了解,所以话不敢说死~

2。第二个比较靠谱,也是不少人正在采用的:用现成的加密算法对资源文件进行加密。


具体流程:

我的游戏关卡文件是以xml形式存在的,

首先我在项目中书写一些代码,这部分代码的作用就是在真机测试app的过程中,

将 xml 文件加密后置入 app 的 Documents 目录下面。

当然,如果能新建一个 command line tool 项目隔离开来做是最好的,电脑的效率比ios 设备高了去了。

我这里也是偷懒了,不过置入项目中的话,今后再回来翻,可能会方便一点。

借助 iExplorer 将 Documents 目录中生成的加密好的关卡文件弄到电脑里面来,

用加密过的关卡文件将项目中之前未加密的关卡文件替换掉,再修改一下关卡加载模块,完工~

下面是一点儿相关的代码,后来我没有采用在游戏项目中对游戏关卡加密的方案,

如上所述,太麻烦了(我直接在我的关卡生成工具里面就把这步给完成了)~


相关代码:

BYSecurity.h

#import <Foundation/Foundation.h>
#import "GCfg.h"
#import "Rc4.h"
#import "SecurityMacros.h"

@interface BYSecurity : NSObject

+(BYSecurity*) security;

-(id) init;

-(void) encryptAllLevels;

@end
BYSecurity.mm

//
//  BYSecurity.mm
//  HungryBear
//
//  Created by Bruce Yang on 12-5-26.
//  Copyright (c) 2012年 EricGameStudio. All rights reserved.
//

#import "BYSecurity.h"

@implementation BYSecurity

+(BYSecurity*) security {
    return [[[self alloc] init] autorelease];
}

-(id) init {
    if((self = [super init])) {
        
    }
    return self;
}

-(BOOL) writeApplicationData:(NSData*)data toFile:(NSString*)fileName {
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* documentsDirectory = [paths objectAtIndex:0];
    if(!documentsDirectory) {
        NSLog(@"Documents directory not found!");
        return NO;
    }
    NSString *appFile = [documentsDirectory stringByAppendingPathComponent:fileName];
    return ([data writeToFile:appFile atomically:YES]);
}

-(void) encryptAllLevels {
    return;
    
    // 0.关卡总数~
    int levelTotalCount = [[GCfg getInstance] ifk:@"levelTotalCount"];
    NSLog(@"levelTotalCount = %d", levelTotalCount);
    
    // 1.documents 目录的绝对路径~
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* documentsDir = [paths objectAtIndex:0];
    if(!documentsDir) {
        NSLog(@"Documents directory not found!");
        return;
    }
    
    NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
    for(int i = 0; i < levelTotalCount; ++ i) {
        // 1。不能仅仅凭借文件名就获取文件的内容,即使是在 ios 平台上面,读取到的 string 为 null~
//        NSString* fileName = [NSString stringWithFormat:@"level_%d.xml", i];
//        NSLog(@"fileName = %@", fileName);
//        NSString* fileContent = [NSString stringWithContentsOfFile:fileName 
//                                                          encoding:NSUTF8StringEncoding 
//                                                             error:nil];
//        NSLog(@"%@", fileContent);
        
        
        // 2。正确写法~
        NSString* fileName = [NSString stringWithFormat:@"level_%d", i];
//        NSLog(@"fileName = %@", fileName);
        NSString* filePath = [NSBundle pathForResource:fileName ofType:@"xml" inDirectory:bundlePath];
        NSString* fileContents = [NSString stringWithContentsOfFile:filePath 
                                                          encoding:NSUTF8StringEncoding 
                                                             error:nil];
//        NSLog(@"%@", fileContent);
        
        
        // 3。加密文件内容~
        NSString* encryptedContents = [Rc4 HloveyRC4:fileContents key:SECURITY_KEY];
        
        
        // 4。在 app 的 documents 目录下生成新的加密文件~
        NSString* newFileName = [NSString stringWithFormat:@"lv%d.y3w", i];
        NSString* newFilePath = [documentsDir stringByAppendingPathComponent:newFileName];
        [[encryptedContents dataUsingEncoding:NSUTF8StringEncoding] writeToFile:newFilePath atomically:YES];
    }
}

@end


原文地址:https://www.cnblogs.com/java20130723/p/3212288.html