搜索
首页后端开发php教程PHP、iOS 使用JSPatch基本与RSA,AES加密

在使用JSPatch时,JS脚本理论上可以调用任意OC方法,权限非常大,若经过HTTP传输时,被中间人攻击篡改js代码,则会造成很大危害。

鉴于此种情况

1. 服务器尽量使用https传输2. 对传输的代码做好加密和校验

接下来,以服务器端使用php,移动端iOS,主要对第二种方式进行处理

RSA算法

RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。

RSA算法是一种非对称加密算法,常被用于加密数据传输.如果配合上数字摘要算法, 也可以用于文件签名.

RSA算法是一种非对称算法,算法需要一对密钥,使用其中一个加密,需要使用另外一个才能解密。我们在进行RSA加密通讯时,就把公钥放在客户端,私钥留在服务器。

一般来说
1.公钥加密,私钥解密2.私钥对文件进行签名,公钥对签名进行验证

公钥、私钥生成

  1. 使用openSSL命令生成密钥

openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem

按照提示,填入私钥的密码(之后会使用),签名证书的组织名、邮件等信息之后,就会生成包含有公钥的证书文件public_key.der和私钥文件private_key.pem。

public_key.der文件用于分发到ios客户端进行公钥加解密,而private_key.pem文件留在服务器端供php使用

openssl rsa -in private_key.pem -pubout -out public_key.pem

此命令会根据输入的私钥文件生成pem格式的公钥文件,这也是把private_key放在服务端的原因

服务端php代码(ThinkPHP框架,加密解密代码与框架无直接关系)

    <?php    /**     * Created by PhpStorm.     * User: and     * Date: 16/2/1     * Time: 10:14     */    namespace Home\Controller;    class RsaController extends CommenController {    //使用文本打开之前获取的private_key.pem可得如下        const PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----    MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAN2DTzqHsIiEw8bQ    R3MT9FpwVzet+kGQphJCFfY6A5u4gK6BuiVKqJpRroJlzg5yT3zy5tzowpSqIuMZ    8104ncih3uvKoNvvPhwjTy6mGHJHoKaGBlnK7oMXOmi50wVA8qvf++kZnxn9W7tM    YnCe6GSkQBS5KgythpIqPaqcaY1dAgMBAAECgYEAjTfqacEZvV8OxRABjQ76qDGY    mOm0cto51cgF4k0IAd21RAt2VdHr/T33yDAJFtKvdFQS9GD7s/VnemsP6K1wgMld    AvV2+KAPK2ZcCNTktLLBmOikJtBYQZGBnaAlxKQD2RFr+YJRCORxSQfOgGVxzch6    tgXC7VyQmddYBvaOEq0CQQD0dRHMxvn8iTa1x+Df4ghE3XZwyG8rDIpMehfAQdm/    hgf5Z1DX56DOG0LD99OMH5wE+C8CHdSP9F842cFJrZjTAkEA5/jlFcQU3vW/6fmk    XshHyaF40s9+5K84i/1EzTW/Wx08zZGql/WrTuQ8QllMAUDR6+kZvPLSPexA/8DS    e8xjDwJAObn7fhPurIfqd3q/y56gvUJe2bs7JTtM3UpnmWrzdJq9/1M6cAGuo30k    gwpe1lQQj8vbrfBFZckbQ12Im1F3KQJBAIBQCY+nnY/SyaxHfWc8S5E5cxbQ1bTz    Q0kT+Cm2sDlbC9X93CogJvkFgFuG/2a2Dyf6EVWVzzuXYkDVzNfTr3sCQQCdTK7v    I+C/aVcGFFYE0ZL5y3zxUtccBdhJNORb2fG5Oa7tqJH2bancuspeoArcpqElH7GQ    Mm9YArj1T6E10X0E    -----END PRIVATE KEY-----';        public function test() {    //此处为了验证,所以取出publick_key.pem中的public_key        $public_key = '-----BEGIN PUBLIC KEY-----    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdg086h7CIhMPG0EdzE/RacFc3    rfpBkKYSQhX2OgObuICugbolSqiaUa6CZc4Ock988ubc6MKUqiLjGfNdOJ3Iod7r    yqDb7z4cI08uphhyR6CmhgZZyu6DFzpoudMFQPKr3/vpGZ8Z/Vu7TGJwnuhkpEAU    uSoMrYaSKj2qnGmNXQIDAQAB    -----END PUBLIC KEY-----';    //之前使用openssl生成private_key时填写的密码    $open_key = '123456';        $pi_key = openssl_pkey_get_private(self::PRIVATE_KEY,$open_key);//这个函数可用来判断私钥是否是可用的,可用返回资源id Resource id        echo $pi_key,"\n";        $pu_key = openssl_pkey_get_public($public_key);//这个函数可用来判断公钥是否是可用的        echo $pu_key,"\n";        $data = "xiaohulu123";//原始数据        $encrypted = "";        $decrypted = "";        echo "source data:",$data,"\n";        echo "private key encrypt:\n";        openssl_public_encrypt($data,$encrypted,$pu_key);//公钥加密,私钥解密        $encrypted = base64_encode($encrypted);//加密后的内容通常含有特殊字符,需要编码转换下,在网络间通过url传输时要注意base64编码是否是url安全的        echo "公钥加密后:",$encrypted,"\n";        openssl_private_decrypt(base64_decode($encrypted),$decrypted,$pi_key);//私钥加密的内容通过公钥可用解密出来        echo "私钥解密:",$decrypted,"\n";        echo "\n","---------------------------------------","\n";        //私钥对数据进行签名,公钥解密验证        $bicode = "";        $cdbicode = "";        openssl_private_encrypt($data, $bicode, $pi_key);        $bicode = base64_encode($bicode);        echo "私钥签名:",$bicode,"\n";        openssl_public_decrypt(base64_decode($bicode), $cdbicode, $pu_key);        echo "公钥验证签名:",$cdbicode,"\n";    }    }

如果得不到resourceID,先查看是否开启openssl扩展,之后查看private_key是否私自添加了缩进等。

=============

iOS使用JSPatch

JSPatch脚本的执行权限很高,若在传输过程中被中间人篡改,会带来很大的安全问题,为了防止这种情况出现,我们在传输过程中对JS文件进行了RSA签名加密,流程如下:

服务端:

  1. 计算 JS 内容 MD5 值。
  2. 用 RSA 私钥对 MD5 值进行加密,与JS内容一起下发给客户端。

客户端:

  1. 拿到加密数据,用 RSA 公钥解密出 MD5 值。
  2. 本地计算返回的 JS 内容 MD5 值。
  3. 对比上述的两个 MD5 值,若相等则校验通过,取 JS 文件保存到本地。由于 RSA 是非对称加密,在没有私钥的情况下第三方无法加密对应的 MD5 值,也就无法伪造 JS 文件,杜绝了 JS 文件在传输过程被篡改的可能。

服务端php代码

/*     * 加密一个字符串,返回RSA加密后的内容     * aString 需要加密的字符串     * return encrypted rsa加密后的字符串     */    public function enjscode($aString) {        $pi_key = openssl_pkey_get_private(self::PRIVATE_KEY);//这个函数可用来判断私钥是否是可用的,可用返回资源id Resource id        openssl_private_encrypt($aString, $encrypted, $pi_key);//私钥加密        $encrypted = base64_encode($encrypted);//加密后的内容通常含有特殊字符,需要编码转换下,在网络间通过url传输时要注意base64编码是否是url安全的        return $encrypted;    }    //JS    public function jscode() {        //$headers = $this->verifyHeaders();        //验证header        //$this->verifyHeadersWithHeaders($headers);        $data['con'] = "defineClass('FindViewController',{viewDidLoad: function() {self.super().viewDidLoad();self.setTitle('发现哈哈');_selectedIndex = 0;self.initView();}})";        $data['isUpdate'] = 'true';       //首先计算js内容的md5值,再将md5值进行RSA加密        $data["ver"] = self::enjscode(md5($data['con']));        $data1['con'] = "require('UIAlertView');defineClass('CircleHotPageViewController',{tableView_didSelectRowAtIndexPath:function(tableView,indexPath){tableView.deselectRowAtIndexPath_animated(indexPath, YES);var alert = UIAlertView.alloc().initWithTitle_message_delegate_cancelButtonTitle_otherButtonTitles('只是提示而已', '测试JSPath!', null, '知道了', null, null);alert.show();}})";        $data1['isUpdate'] = 'true';        $data1["ver"] = self::enjscode(md5($data1['con']));        $this->json_out('200','0','',$da);    }
iOS端代码

由于iOS端原生加解密并不是很好用,所以在此使用github上已经封装好的RSA加解密方法,下载请点击 RSA加密解密

  1. 导入Security.framework
  2. 把public_key.pem中的public_key取出
#define rsa_public_key @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdg086h7CIhMPG0EdzE/RacFc3rfpBkKYSQhX2OgObuICugbolSqiaUa6CZc4Ock988ubc6MKUqiLjGfNdOJ3Iod7ryqDb7z4cI08uphhyR6CmhgZZyu6DFzpoudMFQPKr3/vpGZ8Z/Vu7TGJwnuhkpEAUuSoMrYaSKj2qnGmNXQIDAQAB"

3.在didFinishLaunchingWithOptions方法中进行网络请求,从网络断获取内容data

    /*     *  获取内容为     *  con         js内容     *  isUpdate    是否更新(无用)     *  ver         验证内容,有con 计算md5,再进行rsa加密得来  ->  客户端首页解密得到con的md5值,将此md5值与获取的js内容的md5值进行比较     *           *  若值相等,则说明无篡改;否则,说明被篡改,放弃存储     */    - (void)upJSHandle:(NSDictionary *)response {    NSMutableString *jsString = [NSMutableString string];    for (NSDictionary *di in (NSArray *)response) {        NSString *js = di[@"con"];       //计算获取到的js内容的md5值        NSString *jsMd5 = [MiscTool md5:js];        //解密获取js内容的md5        NSString *cdMd5 = [RSA decryptString:di[@"ver"] publicKey:rsa_public_key];        NSLog(@"cd bicode = %@",cdMd5);        //校验        if (![jsMd5 isEqualToString:cdMd5]) {//经过校验,不相等,说明内容被篡改,直接返回不存储            NSLog(@"zz 内容被篡改!!!");            return;        }        [jsString appendString:js];        //将代码下载到本地,保存成文件Document/up.js, 各个方法之间使用 ***** 分隔符        [jsString appendString:@"*****"];        }        //获取保存js文件内容        NSString *jsPath = [self jsFilePath];        NSLog(@"js xx = 写入 %@",jsString);        //将jsString 进行aes对称加密        //jsString = [self aes:jsString].mutableCopy;        //NSLog(@"xx 加密后 = %@",jsString);        NSData *jsData = [jsString dataUsingEncoding:(NSUTF8StringEncoding)];        //写入文件        [jsData writeToFile:jsPath atomically:YES];        //执行        [self execUpJsWithJsArray:[self readJs]];    }

4.在applicationDidBecomeActive方法,读取js文件,并执行

    #pragma mark -- js 读取    - (NSArray *)readJs {        NSString *file = [self jsFilePath];        NSFileManager *fileManager = [NSFileManager defaultManager];        if(![fileManager fileExistsAtPath:file]) {//如果不存在            return @[];        }        NSString *jsString = [NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil];        //取出后,将jsString 解密        //jsString = [self cdAes:jsString];        //NSLog(@"xx 解密后 = %@",jsString);        NSArray *jsArray = [jsString componentsSeparatedByString:@"*****"];        return jsArray;    }    - (void)execUpJsWithJsArray:(NSArray *)jsArray {        if (jsArray.count == 0) {            return;        }        [JPEngine startEngine];        for (NSString *js in jsArray) {            if ([js isEqualToString:@""] || js == nil) {                continue;            }            NSLog(@"read js = %@",js);            [JPEngine evaluateScript:js];        }    }    - (void)applicationDidBecomeActive:(UIApplication *)application {    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.    //每次进入时执行js    [self execUpJsWithJsArray:[self readJs]];      }

本地存储

本地存储的脚本被篡改的机会小很多,只在越狱机器上有点风险,对此可以在下载完脚本保存到本地时进行对称加密,每次读取时解密。

aes加密解密
    /*     *  进行aes对称加密     */    - (NSString *)aes:(NSString *)aString {        NSString *biCode = [SecurityUtil encryptAESData:aString app_key:aesKey];        //NSLog(@"xx 加密: %@",st);        return biCode;    }    /*     *  对字符串进行aes解密     */    - (NSString *)cdAes:(NSString *)aString {        //NSData *EncryptData1 = [GTMBase64 decodeString:[SecurityUtil encryptAESData:string app_key:aesKey]]; // 解密前进行 GTMBase64 编码        NSData *EncryptData = [GTMBase64 decodeString:aString];        NSString *unCode = [SecurityUtil decryptAESData:EncryptData app_key:aesKey];        //NSLog(@"xx 解密:%@", string1);        return unCode;    }
声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
PHP记录:PHP日志分析的最佳实践PHP记录:PHP日志分析的最佳实践Mar 10, 2025 pm 02:32 PM

PHP日志记录对于监视和调试Web应用程序以及捕获关键事件,错误和运行时行为至关重要。它为系统性能提供了宝贵的见解,有助于识别问题并支持更快的故障排除

在Laravel中使用Flash会话数据在Laravel中使用Flash会话数据Mar 12, 2025 pm 05:08 PM

Laravel使用其直观的闪存方法简化了处理临时会话数据。这非常适合在您的应用程序中显示简短的消息,警报或通知。 默认情况下,数据仅针对后续请求: $请求 -

php中的卷曲:如何在REST API中使用PHP卷曲扩展php中的卷曲:如何在REST API中使用PHP卷曲扩展Mar 14, 2025 am 11:42 AM

PHP客户端URL(curl)扩展是开发人员的强大工具,可以与远程服务器和REST API无缝交互。通过利用Libcurl(备受尊敬的多协议文件传输库),PHP curl促进了有效的执行

简化的HTTP响应在Laravel测试中模拟了简化的HTTP响应在Laravel测试中模拟了Mar 12, 2025 pm 05:09 PM

Laravel 提供简洁的 HTTP 响应模拟语法,简化了 HTTP 交互测试。这种方法显着减少了代码冗余,同时使您的测试模拟更直观。 基本实现提供了多种响应类型快捷方式: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

在Codecanyon上的12个最佳PHP聊天脚本在Codecanyon上的12个最佳PHP聊天脚本Mar 13, 2025 pm 12:08 PM

您是否想为客户最紧迫的问题提供实时的即时解决方案? 实时聊天使您可以与客户进行实时对话,并立即解决他们的问题。它允许您为您的自定义提供更快的服务

解释PHP中晚期静态结合的概念。解释PHP中晚期静态结合的概念。Mar 21, 2025 pm 01:33 PM

文章讨论了PHP 5.3中引入的PHP中的晚期静态结合(LSB),从而允许静态方法的运行时分辨率调用以获得更灵活的继承。 LSB的实用应用和潜在的触摸

自定义/扩展框架:如何添加自定义功能。自定义/扩展框架:如何添加自定义功能。Mar 28, 2025 pm 05:12 PM

本文讨论了将自定义功能添加到框架上,专注于理解体系结构,识别扩展点以及集成和调试的最佳实践。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器