วิธีสร้าง Self Signed SSL Certificate สำหรับทำ HTTPS บน React และ NodeJS

Raviroj Phaiviroj
4 min readJun 10, 2021

--

Outline

  1. เกริ่น
  2. HTTP & HTTPS
  3. SSL Certificate
  4. วิธีสร้าง Self Signed SSL Certificate
  5. วิธีตั้งค่าให้ React ใช้งาน Self Signed SSL Certificate
  6. วิธีตั้งค่าให้ NodeJS ใช้งาน Self Signed SSL Certificate
  7. ข้อควรระวัง

1. เกริ่น

หลังจากที่พวกเราเหล่านักพัฒนาได้สร้างเว็บไซต์ขึ้นมาแล้ว ก็ต้องอยากเผยแพร่ให้ผู้อื่นเข้ามาเยี่ยมชมเข้ามาใช้งานกันใช่ไหมล่ะครับ เพราะงั้นเราก็ต้องนำเว็บของเราขึ้นไปเก็บไว้บนเซิร์ฟเวอร์ ซึ่งในปัจจุบันก็นิยมใช้บริการคลาวด์กัน เพราะค่อนข้างอิสระสามารถสร้าง vm ขึ้นมาบนคลาวด์กี่ตัวก็ได้ แถมยังมีคนคอยดูแลให้อีก แต่ยังมีสิ่งนึงที่ต้องสังเกต ถ้าเรา Deploy ไฟล์เว็บขึ้นไปบน vm ของคลาวด์แล้วไม่ได้มีการปรับแต่งอะไรเพิ่ม เว็บไซต์ของเราอาจจะทำงานอยู่บนโพรโทคอล HTTP ซึ่งไม่ปลอดภัยก็ได้ ดังนั้นในบทความนี้ผมจะมาแนะนำวิธีทำให้เว็บไซต์ของเรามีความปลอดภัยมากขึ้นด้วยการตั้งค่าให้เว็บไซต์ทำงานอยู่บนโพรโทคอล HTTPS นั่นเอง แต่…..วิธีนี้มีข้อควรระวังนิดนึงอยู่ตรงท้ายบทความด้วย อย่าลืมอ่านให้จบกันนะครับ :P

2. HTTP & HTTPS

โพรโทคอล HTTP (Hypertext Transport Protocol) เป็นโพรโทคอลมาตรฐานที่ใช้ในการติดต่อสื่อสารแลกเปลี่ยนข้อมูลกันผ่านอินเทอร์เน็ต ซึ่งหลัก ๆ เราก็จะใช้ในการรับ-ส่งข้อมูลระหว่างเว็บเบราว์เซอร์กับเครื่องเซิร์ฟเวอร์ เมื่อเราเปิดเว็บเบราว์เซอร์เพื่อเข้าชมเว็บไซต์ เว็บเบราว์เซอร์จะทำการส่ง request ผ่านโพรโทคอล HTTP ให้เซิร์ฟเวอร์ส่งข้อมูลมาให้เพื่อแสดงผลบนหน้าจอ แต่การรับ-ส่งข้อมูลกันผ่านโพรโทคอล HTTP จะเป็นการส่งข้อมูลแบบ Clear text ข้อความเปล่า ๆ ที่ไม่ได้มีการเข้ารหัสอะไรไว้ เลยทำให้สามารถถูกบุคคลอื่นดักจับและอ่านข้อมูลได้ง่าย ซึ่งไม่เหมาะกับการรับ-ส่งข้อมูลที่มีความละเอียดอ่อน เช่น ข้อมูลบัตรเครดิต

อ้าว แบบนี้ก็ไม่ควรทำธุรกรรมทางการเงินผ่านอินเทอร์เน็ตสิ” …..ก็ไม่ถึงขนาดนั้นครับ เพราะยังมีอีกโพรโทคอลนึงที่มีความปลอดภัยมากกว่าอยู่ เราก็โดดไปใช้งานโพรโทคอลนั้นแทน ซึ่งเจ้าโพรโทคอลตัวที่ว่านั้นมีชื่อเรียกว่า HTTPS (Hypertext Transfer Protocol over Secure Socket Layer หรือ Http over SSL) โดยข้อมูลที่ถูกส่งผ่านโพรโทคอล HTTPS จะถูกเข้ารหัสด้วย Asymmetric Algorithm ส่งผลให้แม้ว่าข้อมูลจะถูกดักจับไป แต่ก็ไม่สามารถที่จะอ่านข้อมูลนั้นได้รู้เรื่อง ดังนั้น HTTPS จึงถูกนำมาใช้กับเว็บไซต์ที่ต้องการความปลอดภัยของข้อมูลสูงนั่นเอง

3. SSL Certificate

SSL ย่อมาจาก Secure Socket Layer คือ เทคโนโลยีการเข้ารหัสข้อมูลเพื่อเพิ่มความปลอดภัยในการสื่อสารหรือส่งข้อมูลผ่านเครือข่ายอินเทอร์เน็ตโดยเรียกจะใช้งานผ่านโพรโทคอล HTTPS และใช้ SSL Certificate ในการเข้ารหัสข้อมูล

เอ๊ะ! SSL Certificate คืออะไรน่ะเหรอ….. SSL Certificate ก็คือ ไฟล์ที่เก็บข้อมูลเกี่ยวกับเว็บไซต์ และ Public Key ที่ใช้ในการเข้ารหัสข้อมูล (ส่วน Private Key จะเก็บไว้เป็นความลับ) โดย SSL Certificate จะใช้วิธีการเข้ารหัสที่เรียกว่า Public Key Cryptography ซึ่งเป็นการเข้ารหัสด้วยกุญแจ 2 ดอกที่เป็นคู่กัน (กุญแจคือข้อความยาว ๆ ที่ได้จากการสุ่ม) ได้แก่ Public Key กุญแจสาธารณะที่เปิดเผยให้คนอื่นรับรู้ได้ กับ Private Key กุญแจส่วนตัวที่ไม่เปิดเผยให้คนอื่นรับรู้ เมื่อใช้กุญแจนึงในการเข้ารหัส จะต้องใช้กุญแจอีกตัวนึงที่เป็นคู่กันถึงจะถอดรหัสได้

โดยปกติแล้ว SSL Certificate จะถูกออกโดยผู้ให้บริการออกใบรับรอง (Certification Authority — CA) ซึ่งเป็นองค์กรที่มีหน้าที่ในการตรวจสอบตัวตนของผู้ที่ต้องการใบรับรอง SSL Certificate สร้างกุญแจที่ใช้ในการเข้ารหัส และออก SSL certificate

ที่มา https://d1smxttentwwqu.cloudfront.net/wp-content/uploads/2019/07/ca-diagram-b.png

ขั้นตอนในการออก SSL Certificate

  1. ผู้ร้องขอจะต้องสร้าง Public Key และ Private Key
  2. นำ Public Key และข้อมูลของผู้ร้องขอไปเข้ารหัสสร้างออกมาเป็นไฟล์ Certificate Signing Request (CSR)
  3. ทาง CA จะนำไฟล์ CSR ไปตรวจสอบความถูกต้องของผู้ร้องขอ และใช้ Private Key ของทาง CA มาเข้ารหัสกับไฟล์ CSR สร้างออกมาเป็น SSL Certificate

โดย SSL Certificate ที่ถูกออกโดย CA จะได้รับความน่าเชื่อถือจากเว็บเบราว์เซอร์ ซึ่งก็จะมีค่าใช้จ่ายในการออกใบรับรอง

ในบทความนี้เราจะมาสร้าง Self Signed SSL Certificate (SSL Certificate ที่ถูกสร้างโดยใครหรือคอมพิวเตอร์เครื่องใดก็ได้) แบบฟรี เพื่อทำให้เว็บไซต์ของเราทำงานผ่านโพรโตคอล HTTPS กัน

4. วิธีสร้าง Self Signed SSL Certificate

ไลบรารีที่เราจะใช้ในการสร้าง Self Signed SSL Certificate ก็คือ openssl ซึ่งเป็น open-source command ที่นิยมใช้ในการสร้าง Private Key, Certificate Signing Request (CSR), ระบุข้อมูลของ Certificate และติดตั้ง SSL Certificate โดยเราสามารถเช็คเวอร์ชันของ openssl ที่ถูกติดตั้งบนเครื่องได้ด้วยคำสั่ง

openssl version -a

ตัวเลือก -a จะเป็นการบอกให้แสดงข้อมูลทั้งหมดของ openssl ซึ่งคำสั่งนี้จะเป็นการเช็คว่าเครื่องของเราติดตั้ง openssl ไว้เรียบร้อยแล้วหรือยัง ถ้าเราเห็นเลขเวอร์ชันของ openssl ก็หมายความว่าเราพร้อมที่จะสร้าง Self Signed SSL Certificate แล้ว ซึ่งขั้นตอนในการสร้าง Self Signed SSL Certificate ก็จะคล้าย ๆ กับการออก SSL Certificate ของ CA ว่าแล้วเราก็มาเริ่มกันเลยดีกว่า

1. สร้างไฟล์ Private Key

step นี้จะเป็นการสร้าง Private Key ขึ้นมา ซึ่งเราจะต้องเลือกอัลกอริทึมและขนาดของคีย์ที่จะทำการสร้าง ในที่นี้ผมใช้อัลกอริธึมการเข้ารหัสแบบ RSA และมีขนาดของคีย์เป็น 4096 bits ด้วยคำสั่ง

openssl genrsa -out ssl_private.key 4096

คำสั่งนี้จะทำการสร้างไฟล์ Private Key ในไดเร็กทอรีปัจจุบันที่มีชื่อว่า ssl_private.key โดย

  • genrsa : เป็นคำสั่งที่ใช้ในการสร้าง Private Key ด้วยอัลกอริทึม RSA
  • -out ssl_private.key : เป็นการระบุให้ส่งผลลัพธ์ออกมาเป็นไฟล์ ssl_private.key
  • 4096 : เป็นการระบุความยาวของ Private Key ให้เป็น 4096 บิต

2. สร้างไฟล์ Public Key

step นี้จะเป็นการสร้างไฟล์ Public Key จากไฟล์ Private Key ด้วยคำสั่ง

openssl rsa -in ssl_private.key -pubout -out ssl_public.key

คำสั่งนี้จะทำการสร้างไฟล์ Public Key ที่มีชื่อว่า ssl_public.key จากไฟล์ ssl_private.key โดย

  • rsa : เป็นคำสั่งที่ใช้ในการประมวลผล RSA Key
  • -in ssl_private.key : เป็นการระบุไฟล์สำหรับอ่านข้อมูล ในที่นี้ระบุให้อ่านข้อมูลจากไฟล์ ssl_private.key
  • -pubout : คือการระบุประเภทของการส่งออกให้เป็น Public Key
  • -out ssl_public.key : เป็นการระบุให้ส่งผลลัพธ์ออกมาเป็นไฟล์ ssl_public.key

3. สร้างไฟล์ CSR

step นี้จะเป็นการสร้างไฟล์ CSR จาก Private Key ด้วยคำสั่ง

openssl req -new -key ssl_private.key -out ssl.csr

คำสั่งนี้จะเป็นการสร้างไฟล์ CSR ที่มีชื่อว่า ssl.csr จากไฟล์ ssl_private.key โดย

  • req : เป็นการระบุให้สร้าง Certificate Signing Request
  • -new : เป็นการระบุให้สร้าง Certificate Request ขึ้นมาใหม่
  • -key ssl_private.key : เป็นการระบุให้ใช้ไฟล์ ssl_private.key เป็น Private Key
  • -out ssl.csr : เป็นการระบุให้ส่งผลลัพธ์ออกมาเป็นไฟล์ ssl.csr

หลังจากพิมพ์คำสั่งไปแล้ว จะขึ้นคำถามให้เรากรอกข้อมูลตัวตนของผู้ร้องขอลงไป ซึ่งเราจะกรอกหรือไม่กรอกก็ได้ เพราะเรากำลังสร้าง Self Signed SSL Certificate อยู่ แต่ถ้าเรากำลังทำ CSR เพื่อส่งไปขอ Certificate จาก CA ก็จำเป็นต้องกรอก โดยคำถามมีดังนี้

  • Country Name (2 letter code): รหัสประเทศสองตัวที่บริษัทของผู้ร้องขอตั้งอยู่
  • State or Province Name (full name): จังหวัดที่บริษัทของผู้ร้องขอตั้งอยู่
  • Locality Name (e.g., city): เมืองที่บริษัทของผู้ร้องขอตั้งอยู่
  • Organizational Unit Name (e.g., section): ชื่อบริษัทที่จดทะเบียนถูกต้องตามกฎหมาย
  • Common Name (e.g., server FQDN): ชื่อแผนกของผู้ร้องขอ
  • Email Address: อีเมล์ของผู้ร้องขอ

4. สร้างไฟล์ Self Signed SSL Certificate

step นี้จะเป็นการสร้างไฟล์ Self Signed SSL Certificate ขึ้นมา (ซึ่งถ้าเราสร้าง CSR สำหรับส่งไปให้ CA ตรวจสอบก็ไม่ต้องทำ step นี้ครับ เนื่องจากทาง CA จะเป็นฝ่ายทำขั้นตอนนี้เอง) จากการใช้ไฟล์ Private Key เข้ารหัสไฟล์ CSR ด้วยคำสั่ง

openssl x509 -req -days 365 -in ssl.csr -signkey ssl_private.key -out ssl.crt

คำสั่งนี้จะเป็นการสร้างไฟล์ Self Signed SSL Certificate ที่มีชื่อว่า ssl.crt จากการเข้ารหัสไฟล์ CSR ด้วยไฟล์ Private Key โดย

  • x509 : เป็นการระบุให้สร้าง Self Signed SSL Certificate ไม่ใช่การสร้าง Certificate สำหรับส่งไปร้องขอกับทาง CA
  • -req : เป็นการระบุว่าข้อมูลที่รับเข้ามาเป็น Certificate Request ไม่ใช่ Certificate
  • -days 365 : เป็นการระบุอายุของ Self Signed SSL Certificate ในที่นี้กำหนดให้มีอายุ 365 วัน
  • -in ssl.csr : เป็นการระบุไฟล์สำหรับอ่านข้อมูล ในที่นี้ระบุให้อ่านข้อมูลจากไฟล์ ssl.csr
  • -signkey ssl_private.key : เป็นการระบุไฟล์ Private Key ที่ใช้ในการเซ็นต์ ในที่นี้ระบุเป็นไฟล์ ssl_private.key
  • -out ssl.crt: เป็นการระบุให้ส่งผลลัพธ์ออกมาเป็นไฟล์ ssl.crt

ผลลัพธ์สุดท้ายที่ได้ออกมาคือไฟล์ 4 ไฟล์ ได้แก่ ssl_private.key, ssl_public.key, ssl.csr และ ssl.crt ซึ่งเราสามารถเอาไปใช้งานต่อได้เลย

5. วิธีตั้งค่าให้ React ใช้งาน Self Signed SSL Certificate

หลังจากสร้างไฟล์ Certificate แล้ว วิธีตั้งค่า React ให้รันเว็บผ่าน HTTPS ก็สามารถทำได้ง่าย ๆ เลย เพียงแค่กำหนดค่าดังต่อไปนี้เพิ่มลงในไฟล์ .env

HTTPS=true
SSL_CRT_FILE=<ตำแหน่งที่เก็บไฟล์ crt>
SSL_KEY_FILE=<ตำแหน่งที่เก็บไฟล์ key>

ค่าที่เพิ่มลงไปเป็นการระบุให้รันเว็บผ่าน HTTPS โดยใช้ไฟล์ Certificate และไฟล์ Private Key ที่สร้างขึ้นจากหัวข้อที่แล้ว จากนั้นก็ใช้คำสั่ง npm start เพื่อรัน React แค่นี้ก็ได้เว็บที่รันบน HTTPS แล้ว …..ง่ายเนอะ

6. วิธีตั้งค่าให้ NodeJS ใช้งาน Self Signed SSL Certificate

วิธีกำหนดค่าให้ NodeJS สร้าง HTTPS Server ก็ทำได้ไม่ยากแค่เขียน code NodeJS ดังต่อไปนี้

const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync(<ตำแหน่งที่เก็บไฟล์ key>),
cert: fs.readFileSync(<ตำแหน่งที่เก็บไฟล์ crt>)
};
https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world");
}).listen(8000);

หรือถ้าเพื่อน ๆ คนไหนใช้ Express ก็เขียนโค้ดดังต่อไปนี้

const https = require('https');
const fs = require('fs');
const express = require('express');
const https_options = {
key: fs.readFileSync(<ตำแหน่งที่เก็บไฟล์ key>),
cert: fs.readFileSync(<ตำแหน่งที่เก็บไฟล์ crt>)
};
const app = express();
const port = 1150;
const server = https.createServer( https_options , app );
server.listen( port, function () {
console.log('Listening on port ' + server.address().port);
});

จากนั้นก็ run node ด้วยคำสั่ง node <ชื่อไฟล์ NodeJS> แค่นี้ก็ได้เซิร์ฟเวอร์ที่รันอยู่บน HTTPS พร้อมจะนำไปใช้เป็น API แล้ว

7. ข้อควรระวัง

มาถึงช่วงสุดท้ายของบทความแล้วนะครับ หัวข้อนี้จะพูดถึงข้อควรระวัง

ห้ามใช้ Self Signed SSL Certificate บนงาน production ควรใช้สำหรับตอนพัฒนาหรือ debug แพลตฟอร์มเท่านั้น

เนื่องจาก Self Signed SSL Certificate ไม่ได้รับการเชื่อถือจากเว็บเบราว์เซอร์ และยังมีความเสี่ยงต่อข้อมูลที่ละเอียดอ่อน ยิ่งไปกว่านั้น เมื่อเข้าเว็บไซต์แล้วจะแสดงหน้าแจ้งเตือนเว็บไซต์ไม่ปลอดภัย ซึ่งจะทำลาย first impression ของผู้ใช้ และไม่ดีต่อ SEO อีกด้วย ดังนั้นหากต้องการใช้งาน HTTPS บน production แล้วล่ะก็ ให้ใช้ SSL Certificate ที่ได้รับรองจาก CA แทนจะดีกว่า

ถ้าใช้ Self Signed SSL Certificate เวลาผู้ใช้เข้าเว็บก็จะเจอหน้าแจ้งเตือนประมาณนี้

--

--

Raviroj Phaiviroj

I’m Developer, Runner and Reader who want to share my knowledge and experience.