Author: chumnan.i

  • การเข้ารหัสข้อมูลด้วย ORACLE DBMS_CRYPTO

                  ข้อมูลที่ส่งผ่านในโลกอินเตอร์เน็ตอาจมีความจำเป็นต้องเข้ารหัสข้อมูลเพื่อความปลอดภัย แม้ว่าระบบการป้องกันจะดีแค่ไหน แต่การปล่อยข้อมูลในรูปแบบที่อ่านได้ (Plain Text) ให้วิ่งผ่านเน็ตเวิร์ค ดูเป็นสิ่งที่ไม่ปลอดภัยเป็นอย่างยิ่ง

                  ข้อมูลบนระบบจัดการฐานข้อมูล ORACLE มีฟังก์ชันสำหรับการเข้ารหัสข้อมูล (Encrypt) และถอดรหัสข้อมูล (Decrypt) สำหรับข้อความได้ในหลายๆ Algorithm ดังนี้

    ENCRYPT_DESData Encryption Standard. Block cipher. Uses key length of 56 bits.
    ENCRYPT_3DES_2KEYData Encryption Standard. Block cipher. Operates on a block 3 times with 2 keys. Effective key length of 112 bits.
    ENCRYPT_3DESData Encryption Standard. Block cipher. Operates on a block 3 times.
    ENCRYPT_AES128Advanced Encryption Standard. Block cipher. Uses 128-bit key size.
    ENCRYPT_AES192Advanced Encryption Standard. Block cipher. Uses 192-bit key size.
    ENCRYPT_AES256Advanced Encryption Standard. Block cipher. Uses 256-bit key size.
    ENCRYPT_RC4Stream cipher. Uses a secret, randomly generated key unique to each session.

    สำหรับตัวอย่างในวันนี้จะแสดงการเข้ารหัสข้อมูลด้วย Algorithm DES ซึ่งคีย์จะมีความยาว 56 bits

    เนื่องจากการเข้ารหัสและถอดรหัสจะใช้งานคู่กัน ดังนั้นเราสามารถเขียนทั้งสองฟังก์ชันไว้ใน Package ดังนี้

    CREATE OR REPLACE PACKAGE EN_DE
    AS
    FUNCTION ENCRYPT (p_plainText VARCHAR2) RETURN RAW DETERMINISTIC;
    FUNCTION DECRYPT (p_encryptedText RAW) RETURN VARCHAR2 DETERMINISTIC;
    END;
    /
    
    
    CREATE OR REPLACE PACKAGE BODY "EN_DE"
    AS
    encryption_type PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_DES
    + DBMS_CRYPTO.CHAIN_CBC
    + DBMS_CRYPTO.PAD_PKCS5;
       /*
       ENCRYPT_DES is the encryption algorithem. Data Encryption Standard. Block cipher. Uses key length of 56 bits.
       CHAIN_CBC Cipher Block Chaining. Plaintext is XORed with the previous ciphertext block before it is encrypted.
       PAD_PKCS5 Provides padding which complies with the PKCS #5: Password-Based Cryptography Standard
       */
       encryption_key RAW (32) := UTL_RAW.cast_to_raw('OneTwoThree');
    -- The encryption key for DES algorithem, should be 8 bytes or more. 
    
    FUNCTION ENCRYPT (p_plainText VARCHAR2) RETURN RAW DETERMINISTIC
     IS
        encrypted_raw      RAW (32767);
     BEGIN
        encrypted_raw := DBMS_CRYPTO.ENCRYPT
        (
           src => UTL_RAW.CAST_TO_RAW (p_plainText),
           typ => encryption_type,
           KEY => encryption_key
        );
       RETURN encrypted_raw;
     END ENCRYPT;
    
     FUNCTION DECRYPT (p_encryptedText RAW) RETURN VARCHAR2 DETERMINISTIC
     IS
        decrypted_raw      RAW (32767);
     BEGIN
        decrypted_raw := DBMS_CRYPTO.DECRYPT
        (
            src => p_encryptedText,
            typ => encryption_type,
            KEY => encryption_key
        );
        RETURN (UTL_RAW.CAST_TO_VARCHAR2 (decrypted_raw));
     END DECRYPT;

    END;
    /

    
    
    
    
    

    จากคำสั่งการสร้าง Package ข้างต้นเป็นการเข้ารหัสและถอดรหัสโดยใช้ Algorithm แบบ DES การเรียกใช้งานสามารถเรียกผ่านคำสั่งบน SQL Plus ได้ดังภาพ

    จากการทำงานจะพบว่าเราสามารถเข้ารหัสข้อมูลอย่างง่ายด้วย Algorithm DES ได้ หากต้องการใช้ Algorithm อื่น สามารถเปลี่ยนค่าได้จากที่กำหนดไว้ใน Package ได้ โดยต้องคำนึงถึงขนาดของคีย์ที่เข้ารหัสด้วย เช่น AES ต้องมีขนาดคีย์เป็น 128 bits, 256 bits เป็นต้น

  • ว่าด้วยการนับแถวข้อมูลใน ORACLE

                  การนับแถวข้อมูล (Row Count) ในตารางข้อมูล (Table) บน ORACLE จะใช้คำสั่ง SQL พื้นฐานคือ

                                SELECT COUNT(*) FROM table_name;

                  แต่ในบางครั้งข้อมูลที่ไม่ปกติหรือการเพิ่มพารามิเตอร์ในคำสั่ง COUNT อาจทำให้ได้ผลลัพธ์ที่แตกต่างกันได้ดังตัวอย่าง

    ภาพการสร้างตารางข้อมูล table1 และเพิ่มข้อมูล 7 แถว

                  จากภาพเป็นการเพิ่มตารางข้อมูล และเพิ่มข้อมูลในลักษณะที่แตกต่างกันคือ เพิ่มข้อมูลที่ไม่ซ้ำกัน เพิ่มข้อมูลซ้ำกัน เพิ่มข้อมูลที่เป็น NULL ทั้งสิ้น 7 rows

                  เมื่อใช้คำสั่งเรียกดูข้อมูลและนับจำนวนข้อมูลพบว่าข้อมูลถูกแสดงถูกต้อง และสามารถนับได้ 7 rows ถูกต้อง

    ภาพการแสดงข้อมูลและการนับจำนวนแถวข้อมูลแบบพื้นฐาน

                  เมื่อใช้พารามิเตอร์ ALL ในคำสั่ง COUNT จะพบว่าสามารถนับได้ 5 แถว ซึ่งจะหมายถึงการนับเฉพาะแถวที่มีค่าข้อมูล (ยกเว้นแถวที่มี F1 เป็น NULL)

                  การทำงานโดยใช้คำสั่ง SELECT COUNT( ALL f1) FROM table1; จะให้ผลการทำงานเหมือนกับการนับโดยระบุเงื่อนไข SELECT COUNT(*) WHERE f1 IS NOT NULL; ดังรูป

    ภาพการแสดงข้อมูล และการนับข้อมูลโดยใช้พารามิเตอร์ ALL และการระบุเงื่อนไข WHERE …. IS NOT NULL

                  เมื่อใช้พารามิเตอร์ DISTINCT ภายในคำสั่ง COUNT จะพบว่าผลการนับจะแสดงค่าที่ไม่ซ้ำเท่ากับ 4 (ค่าที่นับได้คือ 1,2,3,4) ค่า NULL ใน Row=5,7 ไม่ถูกนับเนื่องจาก NULL ไม่มีค่า

    ภาพแสดงการนับข้อมูลและการนับข้อมูลโดยระบุพารามิเตอร์ DISTINCT

                  สรุปในเบื้องต้นการนับจำนวนแถวใน ORACLE โดยใช้คำสั่ง COUNT นอกจากจะนับจำนวนแบบง่ายด้วยคำสั่ง COUNT(*) แล้ว เราสามารถระบุพารามิเตอร์ให้มีค่าเป็น ALL หรือ DISTINCT ก็จะให้ผลลัพธ์ของการทำงานที่แตกต่างกันได้

  • การใช้งานหน่วยเวลาใน ORACLE ระดับมิลลิวินาที

                  การใช้งานประเภทเวลาใน ORACLE ที่เราใช้งานปกติคือข้อมูลประเภท Date (Data Type=Date) ซึ่งจะเก็บข้อมูลที่มีหน่วยเล็กที่สุดคือ วินาที (second)

                  การใช้งานระบบที่มีผู้ใช้จำนวนมากพร้อมๆกัน ในบางครั้งหน่วยวินาทีอาจไม่ละเอียดพอ จำเป็นต้องใช้หน่วยเวลาที่เล็กกว่าวินาทีคือมิลลิวินาที (1000 มิลลิวินาที = 1 วินาที) ซึ่งใน ORACLE ได้จัดเตรียมข้อมูลประเภทนี้ไว้ให้คือ Timestamp ซึ่งสามารถใช้งานได้ทั้งการสร้างเป็นคอลัมน์ในตารางข้อมูลหรือเป็นตัวแปรใน PL/SQL ดังตัวอย่าง

    การใช้งาน Timestamp ใน SQL

    รูปแสดงการสร้างตาราง

                  จากรูปจะสร้างฟิลด์ประเภท NUMBER, DATE และ TIMESTAMP (ที่ระดับความละเอียด 6 digits) โดยฟิลด์ DATE กำหนด Default Value = SYSDATE และ TIMESTAMP กำหนด Default = SYSTIMESTAMP

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

    รูปเมื่อเพิ่มข้อมูลรายการใหม่ และสืบค้นข้อมูล

                  จากรูปจะพบว่าค่าในฟิลด์ Date1 มีค่าเวลาหน่วยวินาทีเท่ากับ 38 ส่วน Date2 มีค่าเวลาหน่วยวินาทีเป็น 38.779

                  ทดสอบการเพิ่มข้อมูลเพื่อดูค่าเวลาในฟิลด์ Timestamp โดยเพิ่มข้อมูลและหยุด 100 มิลลิวินาที ก่อนเพิ่มรายการถัดไป

    คำสั่งเพิ่มข้อมูล และพัก 0.1 วินาทีก่อนเพิ่มข้อมูลรายการถัดไป
    การสืบค้นข้อมูลเพื่อดูค่า Timestamp ที่รายการ ID = 2 และ 3

                  จากรูปจะพบว่าค่า Date1 ของรายการ 2,3 มีค่าเท่ากันในขณะที่ Date2 (Timestamp) มีค่าต่างกัน

    การใช้งานตัวแปรประเภท Timestamp ใน PL/SQL

                  นอกจาก Timestamp สามารถใช้งานในคำสั่ง SQL แล้ว ยังสามารถใช้งานได้ใน PL/SQL ได้อีกด้วยดังรูป

    รูปแสดงการใช้งานตัวแปรประเภท Timestamp

                  จากรูปเป็นการสร้างตัวแปรประเภท Timestamp และนำค่าข้อมูลในฟิลด์ข้อมูลมาจัดเก็บและแสดง

                  จากบทความนี้สามารถสรุปได้ว่า สามารถใช้งาน Data Type ประเภท Timestamp บน ORACLE เพื่อจัดการกับข้อมูลที่มีผู้ใช้งานระบบหลายคนพร้อมๆกัน ซึ่งจำเป็นต้องใช้หน่วยเวลาที่มีความละเอียดกว่าวินาที