App Transport Security กับ iOS9

หลายคงอาจจะเจอฝันร้ายไปแล้วหลังจากอัพเดท xcode 7.0 ตัวใหม่ แล้วจัดการรันแอพลิเคชันของคุณใน simulator เพื่อจะทดสอบแอพลิเคชันตัวเก่าที่ใช้งานอยู่ แต่อยู่ดีๆ ข่าวร้ายก็มาเคาะประตูบ้าน “เอ๊ะ แอพลิเคชันเรามีปัญหารึเปล่านะ server เรามีปัญหารึเปล่านะ ทำไมข้อมูลไม่ขึ้นมาหล่ะ แต่เอ๊ะเมื่อวานเรายังรันแอพอยู่ได้สบายๆ อยู่เลย โค้ดเราก็ยังไม่ได้แก้อะไรเลยนะ” หลังจากดูอาการแล้ว ก็เหมือนว่าจะไม่มีอะไรที่ทำให้เกิดปัญหา error ก็ไม่ขึ้นมา เช็คดู server ใช้ tool เรียก service แล้วก็ดูเหมือนจะทำงานเป็นปกติ, รีสตาร์ท เครื่องก็แล้วหรือบางคนอาจจะลามไปจุดธูป จุดเทียนบนกับคุณพระคุณเจ้า ปัญหานี้ก็ยังแก้ไม่หาย หลับไปแล้วตื่นมาปัญหาก็ยังอยู่ แล้วปัญหานี้มันมาจากไหนหล่ะ

ใน iOS9 เพิ่มเติมสิ่งที่เรียกว่า App Transport Security ข้อเรียกสั้นๆ ว่า ATS เข้ามาเป็น default behavior ของแอพลิเคชัน สิ่งนี้มันคืออะไร? ก็ตามชื่อมันเลยนั่นแหละ นั่นก็คือ ทำให้แอพลิเคชันนั้นสามารถรับส่งข้อมูลได้ปลอดภัยมากขึ้น แล้วมีอะไรเปลี่ยนแปลงล่ะ? เมื่อต้องการให้การรับส่งข้อมูลปลอดภัยขึ้น เพราะฉะนั้นโดย default ของ ios9 จะปรับปรุงการรับส่งข้อมูลโดย ATS ซึ่งเค้าได้กำหนดให้ การรับส่งข้อมูลระหว่างแอพลิเคชันเองกับเซิร์ฟเวอร์ นั้น ต้องรองรับมาตรฐานต่างๆ ดังนี้

  1. ต้องรองรับ TLS( Transport Layer Security) 1.2 ซึ่งเจ้า TLS 1.2 นั้นพูดง่ายๆ คือรองรับการส่งข้อมูลแบบ https.
  2. การเข้ารหัสต้องเป็นการเข้ารหัสแบบ forward secrecy(คืออะไรช่วยกลับมาอธิบายด้วยนะ)
  3. Cert ต้องเป็นแบบ SHA256 ขึ้นไป
    (อ้างอิงข้อมูลตามลิงค์ด้านล่างสุด)

ใน iOS เวอร์ชันก่อนๆ การคุยกันระหว่างแอพลิเคชันเอง กับ เซิร์ฟเวอร์นั้นเรายังสามารถใช้การส่งข้อมูลแบบยังไม่ใช้ ATS แต่ใน เวอร์ชัน 9 นี้เริ่มมีการบังคับแบบกลายๆ ให้ต้องใช้ ATS เป็นโปรโตคอลที่ใช้ในการสื่อสารข้อมูลระหว่างแอพลิเคชันและ เซิร์ฟเวอร์(เพื่อความปลอดภัย!!!)

ถือเป็นงานหนัก งานนึงของเจ้าของโปรเจคเลยทีเดียวหากต้องการปรับงานบนเซิร์ฟเวอร์ที่มีอยู่ ให้รองรับ ATS นั้นต้องใช้ พลังงานและเวลากันพอสมควรเลยทีเดียว

เมื่อ ATS ถูกนำมาใช้เป็น default behavior ซึ่งมันก็เป็นสิ่งที่ถือว่าถูกต้องที่เราจะต้องใช้อะไรที่มันปลอดภัยกว่า เพื่อปกป้องข้อมูลของผู้ใช้งานแอพลิเคชันของเรา แม้นว่าตอนนี้แอปเปิลจะไม่บังคับให้ใช้ ATS แบบมัดมือชก ยังพอมีวิธีให้ปิด feature นี้อยู่ได้บ้าง แต่เจ้าของโปรเจคทั้งหลาย ก็คงต้องเตรียมแผนการกันได้แล้วแหละว่า จะเริ่มวางแผนปรับโปรเจคของตัวเองจากการสื่อสารแบบเดิมเป็น ATS

ส่วนใครที่ยังไม่พร้อมจะใช้ ATS หรือแอพลิเคชันของตัวเองต้องไปต่อกับ third party api ที่ยังไม่รองรับ ก็ยังมีวิธีที่จะปิด feature นี้แบบชั่วคราว(แต่ถ้าเป็นไปได้ก็ไม่แนะนำ) วิธีการปิดฟีเจอร์นี้ให้เลือกทั้ง ปิดฟีเจอร์นี้เฉพาะ url นั้นๆ หรืออีกอย่าง ปิดมันให้หมดทั้งแอพไปเลย สบายใจดี

วิธีการปิดฟีเจอร์นี้ ก็ต้องไปเปิดไฟล์ Info.plist ตามเอกสารของ apple เหล่านี้คือ property ที่เราสามารถเลือกเปิดหรือปิดได้
App Transport Security1

ถ้าต้องการปิดหมดเลยก็ให้เพิ่ม key นี้เข้าไปในไฟล์ Info.plist

<dict>
  <!– อนุญาติให้ connection ทุกแบบสามารถติดต่อส่งข้อมูลกันได้–>
  <key>NSAllowsArbitraryLoads</key>
      <true/>
</dict>

แต่ถ้าต้องการเลือกปิดแค่บาง url ก็ต้องเพิ่ม key เหล่านี้เข้าไป
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>myserver.com</key>
    <dict>
      <!–อณุญาติให้ใช้ sub domain–>
      <key>NSIncludesSubdomains</key>
      <true/>
      <!–อณุญาติให้ใช้การติดต่อแบบ HTTP –>
      <key>NSExceptionAllowsInsecureHTTPLoads</key>
      <true/>
      <!–ระบุเวอร์ชันต่ำที่สุดของ TLS ที่รองรับ–>
      <key>NSExceptionMinimumTLSVersion</key>
      <string>TLSv1.1</string>
    </dict>
  </dict>
</dict>

แค่นี้แอพลิเคชันที่รันไม่ได้ ก็จะกลับมารันได้เหมือนเมื่อวานนี้และกลับสู่สภาพปกติ

แต่ทั้งนี้ทั้งนั้นก็ขอแนะนำว่า ถ้าทางเซิร์ฟเวอร์ พอที่จะปรับให้รองรับ ATS ได้ก็ยอมเสียเวลาสักหน่อยแล้วทำการย้ายจากการส่งข้อมูลบน ATS กันดีกว่านะไม่นานคงจะถูกบังคับกันแล้ว

ข้อมูลเพิ่มเติม: การปรับฝั่งเซิร์ฟเวอร์ให้รองรับ ATS นั้น จะรองรับ https อย่างเดียวไม่พอจริง ต้องปรับให้มาตรฐานการรับส่งข้อมูลทั้งหมดเป็นไปตามเจ้ามาตรฐาน ATS ทั้งสามข้อด้วย เพราะจากการทดลองแล้วแค่ปรับเป็น https อย่างเดียวบางครั้งก็ไม่สามารถรับส่งข้อมูลได้ งานนี้ก็ยาวกันต่อไป

ข้อมูลอ้างอิง Apple Document, reference