English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

مبدأ التحقق من الشهادات الرقمية الذاتية في HTTPS وغمس بيانات الطلب في iOS

ملخص: في مؤتمر مطوري Apple WWDC 2016، أعلنت Apple عن موعد نهائي: يجب أن تكون جميع التطبيقات في App Store معتمدة على ميزة App Transport Security (ATS) الأمنية بحلول 1 يناير 2017. App Transport Security (ATS) هي ميزة حماية الخصوصية التي أطلقتها Apple في iOS 9، وتقوم بمنع تحميل موارد HTTP النصية العارية، حيث يجب أن تمر الاتصالات عبر HTTPS أكثر أمانًا. يسمح Apple للمطورين بتعطيل ATS مؤقتًا واستخدام الاتصالات عبر HTTP، ولكن يجب أن يستخدم جميع التطبيقات الرسمية في المتاجر الرسمية ATS إلزاميًا بنهاية السنة.

يستخدم المشروع إطار العمل AFNetworking 3.0 وما فوق، بسبب ATS، يسمح iOS باستخدام الروابط التي تبدأ بHttps فقط، قبل 30 ديسمبر 2016 سمحت شركة Apple بتحفيز ATS، كما هو موضح في الشكل التالي:

لكن من تاريخ 1 يناير 2017، لن يتم قبول التطبيقات التي تستخدم http للتحميل المصادر، لذا هذا المقال يشرح كيفية استخدام AFN لشهادة التوقيع الذاتي عبر التحقق (ملاحظة: لا داعي للتحقق من الشهادات التي يتم تصديرها من قبل هيئة التدقيق، يمكن استخدام الروابط التي تبدأ بHttps للوصول إلى البيانات وتحميل الصفحات مباشرة) تم رفع المشروع إلى GitHub (إذا كنت بحاجة إلى مراجعة الشيفرة المصدرية، يرجى الضغط على الرابط):HttpsSignatureCertificate_jb51.rar

1،建立一个根类 此处命名为AKNetPackegeAFN

 1>  .h文件 ,创建所需要的Get 与 Post 方法

#import <Foundation/Foundation.h>
typedef enum{
  AKNetWorkGET ,  /**< GET请求 */
  AKNetWorkPOST = 1 /**< POST请求 */
}AKNetWorkType;
typedef void (^HttpSuccess)(id json);
typedef void (^HttpErro)(NSError* error);
@interface AKNetPackegeAFN : NSObject
+(instancetype)shareHttpManager;
/*
 *
 netWorkType:نوع الطلب GET أو POST
 signature:هل يتم استخدام الشهادة الموقعة، إذا كان الأمر كذلك، يتم كتابة اسم الشهادة، وإلا يتم كتابة nil
 api:رابط واجهة الطلب
 parameters:المواصفات للطلب
 sucess:القيمة التي يتم إرجاعها عند نجاح الطلب
 fail:القيمة التي يتم إرجاعها عند فشل الطلب
 *
 */
- (void)netWorkType:(AKNetWorkType)netWorkType Signature:(NSString *)signature API:(NSString *)api Parameters:(NSDictionary *)parameters Success:(HttpSuccess)sucess Fail:(HttpErro)fail;
@end

2> .m文件,导入头文件AFNetworking.h 新建Manager 属性并实现shareHttpManager类方法

#import "AKNetPackegeAFN.h"
#import "AFNetworking.h"
@interface AKNetPackegeAFN()
@property (nonatomic,strong) AFHTTPSessionManager *manager;
@end
@implementation AKNetPackegeAFN
+(instancetype)shareHttpManager{
  static dispatch_once_t onece = 0;
  static AKNetPackegeAFN *httpManager = nil;
  dispatch_once(&onece, ^(void){
    httpManager = [[self alloc]init];
  });
  return httpManager;
}

2، تنفيذ طرق GET وPOST

عند الاستخدام، قم بتحويل الشهادة المقدمة من قبل الخادم إلى صيغة .cer ثم قم بسحبها إلى مجلد الجذر للمشروع، ثم قم بتحديدها في الدالة مثلًا: اسم الشهادة المقدمة من قبل الخادم: Kuture.crt بعد استلام الشهادة، قم بالضغط عليها مرتين للتركيب، ثم افتح محفظة المفاتيح، وأضغط على الشهادة المسمى Kuture وأدخلها للتصدير، ثم اختر امتداد .cer ثم انقر فوق "موافق" كما هو موضح في الصورة التالية:

  --> -->

-->

طريقة تعبئة GET و POST

- (void)netWorkType:(AKNetWorkType)netWorkType Signature:(NSString *)signature API:(NSString *)api Parameters:(NSDictionary *)parameters Success:(HttpSuccess)sucess Fail:(HttpErro)fail{
  //فتح نمط التحقق من الشهادات
  AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
  //هل يُسمح باستخدام الشهادات الموقعة ذاتياً
  signature == nil ? (void)(securityPolicy.allowInvalidCertificates = NO) : (securityPolicy.allowInvalidCertificates = YES);
  //هل يجب التحقق من اسم النطاق
  securityPolicy.validatesDomainName = NO;
  _manager = [[AFHTTPSessionManager alloc]initWithBaseURL:[NSURL URLWithString:api]];
  _manager.responseSerializer = [AFJSONResponseSerializer serializer];
  _manager.securityPolicy = securityPolicy;
  _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"application/xml",@"text/xml",@"text/json",@"text/plain",@"text/javascript",@"text/html", nil];
  إذا (signature != nil){
    __weak typeof(self) weakSelf = self;
    [_manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential *__autoreleasing *_credential) {
      //الحصول على عنصر الثقة للخادم
      SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
      //استيراد الشهادة الموقّعة ذاتياً
      NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"اسم الشهادة" ofType:@"cer"];
      NSData *cerData = [NSData dataWithContentsOfFile:cerPath];
      إذا (!cerData) {
        NSLog(@"==== .cer file is nil ====");
        return 0;
      }
      NSArray *cerArray = @[cerData];
      weakSelf.manager.securityPolicy.pinnedCertificates = cerArray;
      SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)cerData);
      NSCAssert(caRef != nil, @"caRef is nil");
      NSArray *caArray = @[(__bridge id)(caRef)];
      NSCAssert(caArray != nil, @"caArray is nil");
      //将读取到的证书设置为serverTrust的根证书
      OSStatus status = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)caArray);
      SecTrustSetAnchorCertificatesOnly(serverTrust, NO);
      NSCAssert(errSecSuccess == status, @"SectrustSetAnchorCertificates failed");
      //选择质询认证的处理方式
      NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
      __autoreleasing NSURLCredential *credential = nil;
      //NSURLAuthenTicationMethodServerTrust质询认证方式
      إذا ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        //基于客户端的安全策略来决定是否信任该服务器,不信任则不响应质询
        //إنشاء بطاقة التحدي
          credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
          //تأكيد طريقة التحدي
          if (credential) {
          //استخدام الايمان
            disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
          return disposition;
            if (netWorkType == 0){
          }
        return disposition;
          //إلغاء التحدي
          disposition = NSURLSessionAuthChallengePerformDefaultHandling;
        }
      return disposition;
        if (netWorkType == 0){
      }
      [_manager GET:api parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
    };
  }
  else if (netWorkType == 1){
    }
    }
      if (sucess){
        sucess(responseObject);
      }
        NSLog(@"الارتباط غير صحيح أو لا يوجد شبكة");
      }
    failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
      fail(error);}}
    };
  [_manager POST:api parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
    success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
    }
      if (sucess){
        sucess(responseObject);
      }
        NSLog(@"الارتباط غير صحيح أو لا يوجد شبكة");
      }
    failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
      fail(error);}}
    };
  }  
}

2 طريقة الاستخدام، في الكائنات التي تحتاج إلى الحصول على بيانات أو نقلها، قم بتنفيذ ملف AKNetPackegeAFN.h مباشرة، ويمكن تنفيذ الطريقة، مثلما هو موضح أدناه:

//إنشاء الكائن
  //إذا كانت الشهادة ذات التوقيع الذاتي، قم أولاً بتحديد الشهادة في طريقة AKNetPackegeAFN قبل الاستخدام (الشهادة يتم سحبها مباشرة إلى المشروع)
  /*
   *
   netWorkType:نوع الطلب GET أو POST
   signature:هل يتم استخدام الشهادة الموقعة، إذا كان الأمر كذلك، يتم كتابة اسم الشهادة، وإلا يتم كتابة nil
   api:رابط واجهة الطلب
   parameters:المواصفات للطلب
   sucess:القيمة التي يتم إرجاعها عند نجاح الطلب
   fail:القيمة التي يتم إرجاعها عند فشل الطلب
   *
   */
  AKNetPackegeAFN *netHttps = [AKNetPackegeAFN shareHttpManager];
  [netHttps netWorkType:نوع الطلب Signature:اسم الشهادة API:رابط الطلب Parameters:المواصفات Success:^(id json) {
    NSLog(@"Json:%@",json);
  }; Fail:^(NSError *error) {
    NSLog(@"خطأ:%@",error);
  };

هذا هو محتوى المقال كله، نأمل أن يكون هذا المقال مفيدًا جدًا لكم، ونأمل أيضًا أن تدعموا تعليمات الصراخ.

البيان: محتوى هذا المقال تم جمعه من الإنترنت، ويحق لصاحب الحقوق أن يتحكم فيه، ويتم جمعه من قبل المستخدمين على الإنترنت الذين يقدمون المساهمات ويقومون بالتحميل، ولا يمتلك هذا الموقع حقوق الملكية، ولا يتم تعديل المحتوى بشكل إنساني، ولا يتحمل هذا الموقع أي مسؤولية قانونية. إذا كنت قد وجدت محتوى يشتبه في انتهاك حقوق النسخ، فلا تتردد في إرسال بريد إلكتروني إلى: notice#oldtoolbag.com (عند إرسال البريد الإلكتروني، يرجى استبدال # ب @) لإبلاغنا، وقدم الدليل على الدليل، وسيتم حذف المحتوى المزعوم فور التحقق منه.

الذواقة