目錄
RSA算法
公钥、私钥生成
服务端php代码(ThinkPHP框架,加密解密代码与框架无直接关系)
iOS使用JSPatch
服务端:
客户端:
服务端php代码
本地存储
首頁 後端開發 php教程 PHP、iOS 使用JSPatch基本与RSA,AES加密

PHP、iOS 使用JSPatch基本与RSA,AES加密

Jun 20, 2016 pm 12:34 PM
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

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1325
25
PHP教程
1273
29
C# 教程
1252
24
說明PHP中的安全密碼散列(例如,password_hash,password_verify)。為什麼不使用MD5或SHA1? 說明PHP中的安全密碼散列(例如,password_hash,password_verify)。為什麼不使用MD5或SHA1? Apr 17, 2025 am 12:06 AM

在PHP中,應使用password_hash和password_verify函數實現安全的密碼哈希處理,不應使用MD5或SHA1。1)password_hash生成包含鹽值的哈希,增強安全性。 2)password_verify驗證密碼,通過比較哈希值確保安全。 3)MD5和SHA1易受攻擊且缺乏鹽值,不適合現代密碼安全。

PHP和Python:比較兩種流行的編程語言 PHP和Python:比較兩種流行的編程語言 Apr 14, 2025 am 12:13 AM

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP行動:現實世界中的示例和應用程序 PHP行動:現實世界中的示例和應用程序 Apr 14, 2025 am 12:19 AM

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型? PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型? Apr 17, 2025 am 12:25 AM

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

PHP的持久相關性:它還活著嗎? PHP的持久相關性:它還活著嗎? Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP和Python:代碼示例和比較 PHP和Python:代碼示例和比較 Apr 15, 2025 am 12:07 AM

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

PHP與其他語言:比較 PHP與其他語言:比較 Apr 13, 2025 am 12:19 AM

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

See all articles