Archive for the ‘Misc’ Category

0144 | Enigma code และช่องโหว่ของมัน

Wednesday, January 16th, 2013 Posted in Misc | No Comments »

บังเอิญเจอคลิปจาก channel numberphile ใน youtube มาครับ (เป็น subscriber ของ channel นี้อยู่ ดูเพลินดี) พอดีเค้าอัพคลิปเรื่องเครื่อง Enigma นี้ขึ้นมาพอดี ก็เลยเอามาแปะกันครับ

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

เข้าเรื่อง ไอ้เครื่อง Enigma นี่มันจะไว้เข้ารหัสโดยการแทนที่ตัวอักษรแบบผันแปรครับ คือตัวอักษรเดิม ถ้าเรากดซ้ำๆ ข้อความที่ได้จะเปลี่ยนไปเรื่อยๆ เช่นข้อความต้นแบบคือ aaaaa เวลาเข้ารหัสแล้วอาจออกมาเป็น iudgh อะไรแบบนี้ (อันนี้มั่วมานะ) โดยใช้ jumper ในการเชื่อมสลับคู่ตัวอักษรทั้ง 26 ตัว และแกนหมุน 3 หลักที่ช่วยให้ตัวอักษรหมุนเวียนไปไม่ซ้ำกันเพื่อให้ถอดรหัสได้ยากถ้าไม่รู้การตั้งค่าเริ่มต้นที่ถูกต้องทั้งหมด

พูดไปอาจจะนึกไม่ออก ลองดูคลิปนี้เลยดีกว่าครับ

ทีนี้ ปัญหาของ enigma code นี่มันคือ การที่ตัวอักษรต้นฉบับตัวเดิม จะไม่ได้ถูกแทนที่ด้วยตัวอักษรปลายทางเดิมเสมอเนี่ย มันมีช่องโหว่ว่า มันจะไม่มีวันแทนที่กลับมาเป็นตัวเองโดยเด็ดขาด ถ้ารู้ข้อความต้นฉบับเพียงบางส่วน (อาจจะแค่ 7-8 ตัวอักษร) ก็จะสามารถคำนวณหาค่าตั้งต้นสำหรับชุดคำนั้นได้โดยการทาบข้อความต้นฉบับกับข้อความที่เข้ารหัสแล้ว แล้วไล่ไปเรื่อยๆ ครับ ดูคลิปเลยดีกว่า

ในคลิปมีพูดถึงบุคคลสำคัญของคนที่ทำงานสายคอมพิวเตอร์โปรแกรมมิ่งอยู่ด้วยคนนึงครับ เค้าคือ Alan Turing … ประวัติเป็นไงไปอ่านต่อใน wikipedia ละกันนะครับ (ตึ่ง!)

0138 | function get url ผ่าน https ใช้แทน curl

Monday, December 17th, 2012 Posted in Misc | No Comments »

วันก่อนเจอบั๊กระหว่าง curl + openssl + centos 6 นิดหน่อย
ที่ทำให้ curl และ app ทุกอย่างที่ใช้ libcurl ต่อไปหา server ที่เป็น https บางตัวบนบางเงื่อนไขไม่ได้
หาข้อมูลไปก็พบว่าต้องไปแก้ที่ฝั่ง server (จะบ้าเรอะ server ชาวบ้าน) ไม่ก็ต้องแก้ code ใหม่ให้ใช้ library อย่างอื่นแทน ก็เลยเกิดมาเป็น function นี้ครับ

มี requirement นิดหน่อยคือ PHP 5.3.4 ขึ้นไป และ เปิด allow_url_fopen ไว้ใน php.ini

feature
=> custom header ได้
=> รองรับ cookie โดยอัตโนมัติ
=> method ได้ทั้ง get และ post (รวมถึง post แบบใส่ data ด้วย)
=> url ได้ทั้ง http และ https (มี validate url เผื่อไว้ด้วย)
=> บังคับ verify ssl certificate ที่ฝั่งปลายทางด้วยว่า cert ถูกต้อง (file get content ปกติจะไม่ verify)
=> ใช้ ca file ของ OS (แก้ได้)

<?php
function httpquery($url, $method = 'GET', $headers = array(), $body = '', $returnheader = false, $followlocation = true){
    global $cookies;
    $reqinfo = parse_url($url);
    if (empty($reqinfo['host']) || empty($reqinfo['path'])) return false;
    if (empty($reqinfo['scheme'])) $reqinfo['scheme'] = 'http';
    if ($reqinfo['scheme'] != 'http' && $reqinfo['scheme'] != 'https') {
        trigger_error("Unsupported scheme '".$reqinfo['scheme']."'");
        return false;
    }
    if (empty($reqinfo['port'])) {
        if ($reqinfo['scheme'] == 'https')
            $reqinfo['port'] = 443;
        else
            $reqinfo['port'] = 80;
    }
 
    $headers['User-Agent'] = (!isset($headers['User-Agent']) ? 'Mozilla/4.0 (compatible; icez.net http client)' : $headers['User-Agent']);
    $headers['Host'] = $reqinfo['host'];
    $headers['Accept'] = '*/*';
 
 
    $cdata = array();
    foreach($cookies as $ckey => $cval) {
        $cdata[] = $ckey.'='.$cval;
    }
    $headers['Cookie'] = implode('; ', $cdata); // http_build_query($cookies);
    unset($cdata);
 
    if ($method == 'POST') {
        $headers['Content-Type'] = (isset($headers['Content-Type']) ? $headers['Content-Type'] : 'application/x-www-form-urlencoded');
    }
 
    $headerstring = '';
    foreach ($headers as $header => $content) {
        $headerstring .= $header.': '.$content."\r\n";
    }
 
    $reqpath = $reqinfo['path'].(isset($reqinfo['query']) ? '?'.$reqinfo['query'] : '');
 
    $opts = array('ssl' => array(
            'verify_peer' => true,
            'cafile' => '/etc/pki/tls/certs/ca-bundle.crt'
        ),
        'http' => array(
            'method' => $method,
            'follow_location' => ($followlocation ? 1 : 0),
            'ignore_errors' => true,
            'timeout' => 15,
            'header' => $headerstring
        )
    );
    if (!empty($body)) $opts['http']['content'] = $body;
    $context = stream_context_create($opts);
 
    $stream = fopen($url, 'r', false, $context);
    $meta = stream_get_meta_data($stream);
    $content = stream_get_contents($stream);
    if (!is_array($meta['wrapper_data'])) {
        trigger_error("Invalid HTTP Header Response");
    }
    $header = '';
 
    foreach($meta['wrapper_data'] as $header) {
        if (strpos($header, ':') !== false) {
            $line = explode(':', $header, 2);
            if (strtolower($line[0]) == 'set-cookie') {
                $cookie = explode(';', trim($line[1]), 2);
                if (strpos($cookie[0], '=') !== false) {
                    //valid cookie
                    $cdata = explode('=', $cookie[0], 2);
                    $cookies[$cdata[0]] = $cdata[1];
                }
            }
        }
    }
    fclose($stream);
    if ($returnheader) $content = implode("\r\n", $meta['wrapper_data'])."\r\n\r\n".$content;
    return $content;
}
?>