다양한 기능 추가 (삭제, 검색, 화면단위 출력)

▶ 삭제 및 검색, 화면단위 출력 기능

위와 같이 검색기능을 활성화 할 것이다.

 

st_vi.php

<form name='search' method='post' action='st_vi.php'>
 검색창 &nbsp;<input type='text' name='search'>
		   <input type='submit' name='확인' value='확인'>
 </form>


<?
  echo("<a href=./st_in.html>자료 입력하기</a><hr>");

  require('conn.php');

  //==========================삭제기능========================================
  $del=$_GET[del];        // $del 변수가 null이 아니면 행을 삭제하는 else절이 실행된다.
  if (empty($del)){}
  else {
	  $sql="delete from student where sno='$del'";
	  $result=oci_parse($conn,$sql);
	  oci_execute($result);
	  oci_free_statement($result);
	  }

  //==========================검색기능=========================================

    $search = $_POST[search];
	if (empty($search))
	{
	 	$sql="select sno,sname,sex,major,syear,to_char(avr,'0.00') avr
	 	from student order by sno";
	 	$result=oci_parse($conn,$sql);
	 }
	else
	{
	 	$sql="select sno,sname,sex,major,syear,to_char(avr,'0.00') avr
	 	       from student
	 	       where sname like '%{$search}%' order by sno";
	 	$result=oci_parse($conn,$sql);
	 }
	 oci_execute($result);

  //==========================================================================


  $row_num=oci_fetch_all($result, $row);  // $row_num : 전제 행의 수
  echo("Row의 개수는 $row_num 입니다.<br><hr>"); // 행은 컬럼명, 열은 헹번호

  oci_free_statement($result);
  oci_close($conn);

   $scale=5;                           // 화면에 출력할 행의 개수
   $start = $_GET[start];
   if (empty($start)){$start=0;}    // 첫 화면은 0에서 시작, 배열의 키값은 0에서 시작

  echo("<table border='1'>");
  for($i=$start; $i<($start+$scale); $i++) {
   if ($i<$row_num){
     echo("
    	<tr>
    		<td width='50'><p align='center'>{$row['SNO'][$i]}</p></td>
    		<td width='80'><p align='center'>{$row['SNAME'][$i]}</p></td>
    		<td width='20'><p align='center'>{$row['SEX'][$i]}</p></td>
    		<td width='20'><p align='center'>{$row['SYEAR'][$i]}</p></td>
    		<td width='50'><p align='center'>{$row['MAJOR'][$i]}</p></td>
    		<td width='30'><p align='center'>{$row['AVR'][$i]}</p></td>
    		<td width='30'><a href=./st_vi.php?del={$row[SNO][$i]}>del</a></td>
    	</tr>
    	");
  	}
	}
   echo("</table><hr>");

  $p=$start-$scale;     // 이전 화면의 시작 위치
  $n=$start+$scale;     // 다음 화면의 시작 위치

  if($p>=0)
    echo("<a href=./st_vi.php?start=$p>[이전페이지]</a>&nbsp;&nbsp;");
  else
    echo("이전페이지&nbsp;&nbsp;");
  if($n<$row_num)
    echo("<a href=./st_vi.php?start=$n>[다음페이지]</a>");
  else
    echo("다음페이지");
?>

검색 실행결과
화면단위 실행결과


위 방식으로 프로그램을 구성할 경우 오류가 있다.

다음페이지를 눌렀을 경우 search 변수가 유지가 되지 않아서 다음페이지를 다시 처음부터 받아오는 경우가 생긴다.

search 변수를 출력함으로써 search 변수가 유지되지 않는 것을 확인할 수 있다.

 

수정된 st_vi.php

<form name='search' method='get' action='st_vi.php'>
 검색창 &nbsp;<input type='text' name='search'>
		   <input type='submit' name='확인' value='확인'>
 </form>


<?
  echo("<a href=./st_in.html>자료 입력하기</a><hr>");

  require('conn.php');

  //==========================삭제기능========================================
  $del=$_GET[del];        // $del 변수가 null이 아니면 행을 삭제하는 else절이 실행된다.
  if (empty($del)){}
  else {
	  $sql="delete from student where sno='$del'";
	  $result=oci_parse($conn,$sql);
	  oci_execute($result);
	  oci_free_statement($result);
	  }

  //==========================검색기능=========================================

    $search = $_GET[search];
	if (empty($search)) {
	 	$sql="select sno,sname,sex,major,syear,to_char(avr,'0.00') avr
	 	     from student order by sno";
	 	$result=oci_parse($conn,$sql);
	 }
	else {
	 	$sql="select sno,sname,sex,major,syear,to_char(avr,'0.00') avr
	 	       from student
	 	       where sname like '%{$search}%' order by sno";
	 	$result=oci_parse($conn,$sql);
	 }
	 oci_execute($result);

  //==========================================================================


  $row_num=oci_fetch_all($result, $row);  // $row_num : 전제 행의 수
  echo("Row의 개수는 $row_num 입니다.<br><hr>"); // 행은 컬럼명, 열은 헹번호

  oci_free_statement($result);
  oci_close($conn);

   $scale=5;                           // 화면에 출력할 행의 개수
   $start = $_GET[start];
   if (empty($start)){$start=0;}    // 첫 화면은 0에서 시작, 배열의 키값은 0에서 시작

  echo("<table border='1'>");
  for($i=$start; $i<($start+$scale); $i++) {
   if ($i<$row_num){
     echo("
    	<tr>
    		<td width='50'><p align='center'>{$row['SNO'][$i]}</p></td>
    		<td width='80'><p align='center'>{$row['SNAME'][$i]}</p></td>
    		<td width='20'><p align='center'>{$row['SEX'][$i]}</p></td>
    		<td width='20'><p align='center'>{$row['SYEAR'][$i]}</p></td>
    		<td width='50'><p align='center'>{$row['MAJOR'][$i]}</p></td>
    		<td width='30'><p align='center'>{$row['AVR'][$i]}</p></td>
    		<td width='30'><a href=./st_vi.php?del={$row[SNO][$i]}>del</a></td>
    	</tr>
    	");
  	}
	}
   echo("</table><hr>");

  $p=$start-$scale;     // 이전 화면의 시작 위치
  $n=$start+$scale;     // 다음 화면의 시작 위치

  if($p>=0)
    echo("<a href=./st_vi.php?start=$p&search=$search>[이전페이지]</a>&nbsp;&nbsp;");
  else
    echo("이전페이지&nbsp;&nbsp;");
  if($n<$row_num)
    echo("<a href=./st_vi.php?start=$n&search=$search>[다음페이지]</a>");
  else
    echo("다음페이지");

  echo("<br>");
  echo($search); // 확인하기 위해 search 변수 출력
?>

실행결과

search 변수가 잘 유지되는 것을 확인할 수 있다.


관계(Relationship)을 가진 테이블에 대한 입출력

▶ 유효한 데이터 확인

course(과목) 테이블 입력 폼과 프로그램

co_in.html

<html><head>
<meta http-equiv="content-type" content="text/html; charset=euc-kr">
<title> course 입력폼 </title>
</head>
<body bgcolor="white" text="black" link="blue" vlink="purple" alink="red">
<form name="insert" action="co_in.php" method="POST">
<center>
<table border="0" width="300">
  <tr>
    <td width="70"><p align="center">과목번호</p></td>
    <td>&nbsp;&nbsp;<input type="text" name="cno"></td>
  </tr>
  <tr>
    <td width="50"><p align="center">과목명</p></td>
    <td>&nbsp;&nbsp;<input type="text" name="cname"></td>
  </tr>
  <tr>
    <td width="50"><p align="center">학점수</p></td>
    <td>&nbsp;&nbsp;1<input type="radio" name="st_num" value="1">,
    2<input type="radio" name="st_num" value="2">,
    3<input type="radio" name="st_num" value="3">,
    4<input type="radio" name="st_num" value="4"></td>
  </tr>
  <tr>
    <td width="70"><p align="center">교수번호</p></td>
    <td>&nbsp;&nbsp;<input type="text" name="pno"></td>
  </tr>
  <tr>
    <td colspan="2">
    <p align="center"><input type="submit" name="확인" value="확인"></p>
  </td>
  </tr>
<table>
</form>
</body></html>

이런식으로 과목명을 입력할 경우 교수번호를 알아야하는데 우리는 알 수가 없다. 따라서 아래처럼 교수이름을 출력하도록 수정한다.

 

수정후 co_in.html

<html><head>
<meta http-equiv="content-type" content="text/html; charset=euc-kr">
<title> course 입력폼 </title>
</head>
<body bgcolor="white" text="black" link="blue" vlink="purple" alink="red">
<form name="insert" action="co_in.php" method="POST">
<center>
<table border="0" width="300">
  <tr>
    <td width="70"><p align="center">과목번호</p></td>
    <td>&nbsp;&nbsp;<input type="text" name="cno"></td>
  </tr>
  <tr>
    <td width="70"><p align="center">과목명</p></td>
    <td>&nbsp;&nbsp;<input type="text" name="cname"></td>
  </tr>
  <tr>
    <td width="70"><p align="center">학점수</p></td>
    <td>&nbsp;&nbsp;1<input type="radio" name="st_num" value="1">,
    2<input type="radio" name="st_num" value="2">,
    3<input type="radio" name="st_num" value="3">,
    4<input type="radio" name="st_num" value="4"></td>
  </tr>
  <tr>
  <td width="70"><p align="center">교수</p></td>
    <td><select name="pno">

    <?
      require('conn.php');
      $sql="select pno, pname
            from professor"; // professor 테이블에서 pno와 pname만 검색한다.
      $result=oci_parse($conn,$sql);
      oci_execute($result);
      $row_num=oci_fetch_all($result, $row);
      for ($i=0; $i<$row_num; $i++) {
          echo("<option value='{$row[PNO][$i]}'>{$row[PNAME][$i]}</option>");
        }
      oci_free_statement($result);
      oci_close($conn);
    ?>
        <option value=""></option>
    </td>
  </tr>
  <tr>
    <td colspan="2">
      <p align="center"><input type="submit" name="확인" value="확인"></p>
    </td>
  </tr>
<table>
</form>
</body></html>

 

co_in.php

<?
  $cno = $_POST[cno];
  $cname = $_POST[cname];
  $st_num = $_POST[st_num];
  $pno = $_POST[pno];

  require('conn.php');

  $sql="insert into course (cno, cname, st_num, pno)
        values ('$cno', '$cname', $st_num, '$pno')";

  $result=oci_parse($conn,$sql);
  $re=@oci_execute($result);

  oci_free_statement($result);
  oci_close($conn);

  if(!$re)
    { echo(" <script>
            window.alert('과목 입력 장애 입니다.');
            history.go(-1);
            </script>
          ");
      exit;
    }
  else
    echo(" <meta http-equiv='Refresh' content = '0; URL=co_vi.php'>");
?>

 

sc_in.html

<html><head>
<meta http-equiv="content-type" content="text/html; charset=euc-kr">
<title> score 입력폼 </title>
</head>
<body bgcolor="white" text="black" link="blue" vlink="purple" alink="red">
<form name="insert" action="sc_in.php" method="POST">
<center>
<table border="0" width="300">
  <tr>
    <td width="70"><p align="center">학생</p></td>
    <td><select name="sno">
      <?
      require('conn.php'); // 학생의 명단을 나열한다.
      $sql="select sno, sname
          from student";
      $result=oci_parse($conn,$sql);
      oci_execute($result);
      $row_num=oci_fetch_all($result, $row);
      for ($i=0; $i<$row_num; $i++) {
          echo("<option value='{$row[SNO][$i]}'>{$row[SNAME][$i]}</option>");
        }
      oci_free_statement($result);
      ?>
    </td>
  </tr>
  <tr>
    <td width="50"><p align="center">과목</p></td>
    <td><select name="cno">
      <?
      $sql="select cno, cname
            from course"; // 과목정보를 나열한다.
      $result=oci_parse($conn,$sql);
      oci_execute($result);
      $row_num=oci_fetch_all($result, $row);
      oci_free_statement($result);
      oci_close($conn);
      for ($i=0; $i<$row_num; $i++) {
          echo("<option value='{$row[CNO][$i]}'>{$row[CNAME][$i]}</option>");
        }
      ?>
    </td>
  </tr>
  <tr>
    <td width="50"><p align="center">점수</p></td>
    <td><input type="text" name="res"></td>
  </tr>
  <tr>
    <td colspan="2">
    <p align="center"><input type="submit" name="확인" value="확인"></p>
    </td>
  </tr>
<table>
</form>
</body></html>

 

sc_in.php

<?
  $sno = $_POST[sno];
  $cno = $_POST[cno];
  $sc_result = $_POST[sc_result];

  require('conn.php');

  $sql="insert into score (sno, cno, sc_result)
        values ('$sno', '$cno', '$sc_result')";

  $result=oci_parse($conn,$sql);
  $re=@oci_execute($result);

  oci_free_statement($result);
  oci_close($conn);

  if(!$re)
    { echo(" <script>
            window.alert('기말고사 점수 입력 장애 입니다.');
            history.go(-1);
            </script>
          ");
      exit;
    }
  else
    echo(" <meta http-equiv='Refresh' content = '0; URL=sc_vi.php'>");
?>

추가된 것을 확인할 수 있다.

 

'PHP 공부 기록' 카테고리의 다른 글

PHP 9 - 세션  (0) 2021.12.24
PHP 7 - PHP와 오라클 연동 (입출력 프로그램)  (0) 2021.12.24
PHP 6 - PHP를 이용한 DB 접속  (0) 2021.12.12
(수정중) PHP 5 - 배열  (0) 2021.11.23
PHP 4 - 폼(Form)  (0) 2021.11.19

오라클 연동할 테이블 구조


오라클 입력 프로그램

 

입력 프로그램 실습

student, professor 테이블 입력 프로그램 만들기

 

student table 입력 프로그램

st_in.html

<html><head>
<meta http-equiv="content-type" content="text/html; charset=euc-kr">
<title> student 입력폼 </title>
</head>
<body bgcolor="white" text="black" link="blue" vlink="purple" alink="red">
<form name="insert" action="st_in.php" method="POST">
<center>
<table border="0" width="250">
  <tr>
    <td width="50"><p align="center">학번</p></td>
    <td>&nbsp;&nbsp;<input type="text" name="sno"></td>
  </tr>
  <tr>
    <td width="50"><p align="center">이름</p></td>
    <td>&nbsp;&nbsp;<input type="text" name="sname"></td>
  </tr>
  <tr>
    <td width="50"><p align="center">성별</p></td>
    <td>&nbsp;&nbsp;남<input type="radio" name="sex" value="남">,
                    여<input type="radio" name="sex" value="여"></td>
  </tr>
  <tr>
    <td width="50"><p align="center">학과</p></td>
    <td>&nbsp;&nbsp;<select name="major" size="1">
                      <option value="화학">화학</option>
                      <option value="생물">생물</option>
                      <option value="물리">물리</option>
                      <option value="유공">유공</option>
                      <option value="식영">식영</option></td>
  </tr>
  <tr>
    <td width="50"><p align="center">학년</p></td>
    <td>&nbsp;&nbsp;1<input type="radio" name="syear" value="1">,
                    2<input type="radio" name="syear" value="2">,
                    3<input type="radio" name="syear" value="3">,
                    4<input type="radio" name="syear" value="4"></td>
  </tr>
  <tr>
    <td width="50"><p align="center">학점</p></td>
    <td>&nbsp;&nbsp;<input type="text" name="avr"></td>
    </tr>
  <tr>
    <td colspan="2">
      <p align="center"><input type="submit" name="확인" value="확인"></p>
    </td>
  </tr>
</table>
</form>
</body></html>

 

st_in.php

<?
  $sno = $_POST[sno];
  $sname = $_POST[sname];
  $sex = $_POST[sex];
  $major = $_POST[major];
  $syear = $_POST[syear];
  $avr = $_POST[avr];

  require('conn.php');

  $sql="insert into student (sno, sname, sex, major, syear, avr)
        values ('$sno', '$sname', '$sex', '$major', $syear, $avr)";

  $result=oci_parse($conn,$sql); // SQL문을 파싱해서 실행 계획을 생성한다.
  $re=oci_execute($result); // SQL문을 실행한다.

  oci_free_statement($result);
  oci_close($conn);

  if($re) echo("정상 입력 되었습니다.");
// echo(" <meta http-equiv='Refresh' content = '0; URL=st_vi.php'>");
?>

 

윈도우 cmd 창에서 sqlplus st04/st04@dal로 접속 후 테스트

SQL> SELECT * FROM student WHERE sno=202112;

SNO     SNAME      SEX      SYEAR MAJOR          AVR
------- ---------- --- ---------- ------- ----------
202112  학생임     여           3 화학           4.5

 

professor table 입력 프로그램

pr_in.html

<html><head>
<meta http-equiv="content-type" content="text/html; charset=euc-kr">
<title> professor 입력폼 </title>
</head>
<body bgcolor="white" text="black" link="blue" vlink="purple" alink="red">
<form name="insert" action="pro_in.php" method="POST">
<center>
<table border="0" width="250">
  <tr>
    <td width="50"><p align="center">교수번호</p></td>
    <td>&nbsp;&nbsp;<input type="text" name="pno"></td>
  </tr>
  <tr>
    <td width="50"><p align="center">교수이름</p></td>
    <td>&nbsp;&nbsp;<input type="text" name="pname"></td>
  </tr>
  <tr>
    <td width="50"><p align="center">학과</p></td>
    <td>&nbsp;&nbsp;<select name="section" size="1">
                      <option value="화학">화학</option>
                      <option value="생물">생물</option>
                      <option value="물리">물리</option>
                      <option value="유공">유공</option>
                      <option value="식영">식영</option></td>
  </tr>
  <tr>
    <td width="50"><p align="center">직위</p></td>
    <td>&nbsp;&nbsp;<select name="orders" size="1">
                      <option value="정교수">정교수</option>
                      <option value="부교수">부교수</option>
                      <option value="조교수">조교수</option>
  </tr>
  <tr>
    <td width="50"><p align="center">부임일</p></td>
    <td>&nbsp;&nbsp;<input type="date" name="hiredate"></td>
    </tr>
  <tr>
    <td colspan="2">
      <p align="center"><input type="submit" name="확인" value="확인"></p>
    </td>
  </tr>
</table>
</form>
</body></html>

 

pro_in.php

<?
  $pno = $_POST[pno];
  $pname = $_POST[pname];
  $section = $_POST[section];
  $orders = $_POST[orders];
  $hiredate = $_POST[hiredate];

  require('conn.php');

  $sql="insert into professor (pno, pname, section, orders, hiredate)
        values ('$pno', '$pname', '$section', '$orders', TO_DATE('$hiredate', 'YYYY/MM/DD'))";

  $result=oci_parse($conn,$sql); // SQL문을 파싱해서 실행 계획을 생성한다.
  $re=oci_execute($result); // SQL문을 실행한다.

  oci_free_statement($result);
  oci_close($conn);

  if($re) echo("정상 입력 되었습니다.");
// echo(" <meta http-equiv='Refresh' content = '0; URL=st_vi.php'>");
?>

 

윈도우 cmd 창에서 sqlplus st04/st04@dal로 접속 후 테스트

SQL> SELECT * FROM professor WHERE pno=2021;

PNO     PNAME      SECTION ORDERS  HIREDATE
------- ---------- ------- ------- ----------
2021    교수다     물리    정교수  2021/07/05

 


출력 프로그램

패치 작업을 행의 개수만큼 한다.

OCI_NUM : 배열의 키값을 숫자로 바꾼다.

OCI_ASSOC : 배열의 키값이 컬럼 이름으로 바꿔준다.

$row 라고하는 일차원배열을 생성해 출력한다.

$result는 계속 한 행씩 가져간다.

 

OCI_ASSOC 를 이용한 출력프로그램 생성

st_vi.php

<?
  echo("<a href=./st_in.html>자료 입력하기</a><hr>");

  require('conn.php');

  $sql="select sno, sname, sex, major, syear, to_char(avr,'0.00') avr
        from student order by sno"; //결과값이 resource로 넘어옴.

  $result=oci_parse($conn,$sql); //먼저 파싱한다.
  oci_execute($result); //execute 하면 $result가 테이블 컬럼 첫번째 값을 가리킴

  echo("<table border='0'>");
  while ($row = oci_fetch_array($result, OCI_ASSOC)){
    echo("
          <tr>
              <td width='50'><p align='center'>{$row['SNO']}</p></td>
              <td width='80'><p align='center'>{$row['SNAME']}</p></td>
              <td width='20'><p align='center'>{$row['SEX']}</p></td>
              <td width='20'><p align='center'>{$row['SYEAR']}</p></td>
              <td width='50'><p align='center'>{$row['MAJOR']}</p></td>
              <td width='30'><p align='center'>{$row['AVR']}</p></td>
          </tr>
        ");
      }
  echo("</table>");
  oci_free_statement($result);
  oci_close($conn);
?>

 

pr_vi.php

<?
  echo("<a href=./pro_in.html>자료 입력하기</a><hr>");

  require('conn.php');

  $sql="select pno, pname, section, orders, to_char(hiredate, 'YYYY/MM/DD') hiredate
        from professor order by pno";

  $result=oci_parse($conn,$sql);
  oci_execute($result);

  echo("<table border='0'>");
  while ($row = oci_fetch_array($result, OCI_ASSOC)){
    echo("
          <tr>
              <td width='50'><p align='center'>{$row['PNO']}</p></td>
              <td width='80'><p align='center'>{$row['PNAME']}</p></td>
              <td width='50'><p align='center'>{$row['SECTION']}</p></td>
              <td width='50'><p align='center'>{$row['ORDERS']}</p></td>
              <td width='100'><p align='center'>{$row['HIREDATE']}</p></td>
          </tr>
        ");
      }
  echo("</table>");
  oci_free_statement($result);
  oci_close($conn);
?>

 

* AP 서버 설치 환경

호스트명 : ap
IP : 192.168.10.19
아파치 서버 경로 : /app/apache
아파치 : 2.2.34 (httpd-2.2.34.tar.gz)
PHP : 5.6.39 (php-5.6.39.tar.gz)
오라클 인스턴스 클라이언트 : 19.5.0.0.0

 

$ORACLE_BASE : /app/ora19c
$ORACLE_HOME : /app/ora19c/19c


* 설치 과정

step 1. 오라클 인스턴스 클라이언트 설치
step 2. Apache 설치
step 3. PHP 설치
step 4. Apache, PHP 설정
step 5. 서버 실행 후 연동 확인

 

[root@CentOS7-3 ~]# vi /etc/rc.d/rc.local
[root@CentOS7-3 ~]# /app/apache/bin/apachectl stop
[root@CentOS7-3 ~]#


이미 설치된 아파치를 삭제하고 시작한다.

[root@CentOS7-3 ~]# cd /app/apache
[root@CentOS7-3 apache]# ls
bin    cgi-bin  error   icons    lib   man     modules
build  conf     htdocs  include  logs  manual
[root@CentOS7-3 apache]# cd
[root@CentOS7-3 ~]# rm -rf /app/apache
[root@CentOS7-3 ~]# cd /app/apache
-bash: cd: /app/apache: 그런 파일이나 디렉터리가 없습니다

 

step 1. 오라클 인스턴스 클라이언트 설치

① 설치할 오라클 인스턴스 클라이언트는 오라클 한국어 사이트인 https://www.oracle.com/kr/index.ht
ml 에서 oracle-instantclient19.5-basic-19.5.0.0.0-1.x86_64.rpm 와 oracle-instantclient19.5-devel-
19.5.0.0.0-1.x86_64.rpm 두 개의 파일을 다운 받는다.

ftp서버에 있으므로 ftp로 다운 받을 것이다.

[root@CentOS7-3 ~]# ls
anaconda-ks.cfg                                         공개      사진
initial-setup-ks.cfg                                    다운로드  서식
oracle-instantclient19.5-basic-19.5.0.0.0-1.x86_64.rpm  문서      음악
oracle-instantclient19.5-devel-19.5.0.0.0-1.x86_64.rpm  바탕화면
pcre-8.45.tar.gz                                        비디오

 

② /usr/lib/oracle/19.5을 ORACLE_BASE 디렉토리로 설치된다.

[root@CentOS7-3 ~]# rpm -Uvh oracle-instantclient19.5-basic-19.5.0.0.0-1.x86_64.rpm
준비 중...                         ################################# [100%]
Updating / installing...
   1:oracle-instantclient19.5-basic-19################################# [100%]
[root@CentOS7-3 ~]# rpm -Uvh oracle-instantclient19.5-devel-19.5.0.0.0-1.x86_64.rpm
준비 중...                         ################################# [100%]
Updating / installing...
   1:oracle-instantclient19.5-devel-19################################# [100%]

 

③ sqlnet.ora 파일과 tnsnames.ora 파일을 생성한다.

[root@CentOS7-3 ~]# mkdir -p /usr/lib/oracle/network/admin/
[root@CentOS7-3 ~]# vi /usr/lib/oracle/network/admin/sqlnet.ora
[root@CentOS7-3 ~]# cat /usr/lib/oracle/network/admin/sqlnet.ora
NAMES.DIRECTORY_PATH= (TNSNAMES)

 

tnsnames.ora 파일을 수정한다.

[root@CentOS7-3 ~]# vi /usr/lib/oracle/network/admin/tnsnames.ora
[root@CentOS7-3 ~]# cat /usr/lib/oracle/network/admin/tnsnames.ora
oracle =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = tcp)(HOST = 192.168.11.135)(port = 1521))
      (CONNECT_DATA = (SID = DB19))
    )

ora =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = tcp)(HOST = 192.168.10.138)(port = 1521))
      (CONNECT_DATA = (SID = DB19))
    )

dal =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = tcp)(HOST = 192.168.10.11)(port = 1521))
      (CONNECT_DATA = (SID = DB19))
    )

 

step 2. Apache 설치

① httpd-2.X 소스파일을 /usr/local/에 다운받고 압축을 해제한다.

[root@CentOS7-3 ~]# cd /usr/local/
[root@CentOS7-3 local]# ls
apache2                games                include    pcre-8.45.tar.gz   share
apr-1.6.5.tar.gz       httpd-2.2.34         lib        php                src
apr-util-1.6.1.tar.gz  httpd-2.2.34.tar.gz  lib64      php-7.4.26         var
bin                    httpd-2.4.51         libexec    php-7.4.26.tar.gz
etc                    httpd-2.4.51.tar.gz  pcre-8.45  sbin
[root@CentOS7-3 local]# cd ./httpd-2.2.34

 

② configure → make → make install 순으로 컴파일 설치한다. 그 뒤에 여기부터 하기

[root@CentOS7-3 httpd-2.2.34]# ./configure --prefix=/app/apache --enable-rewrite --enable-so
[root@CentOS7-3 httpd-2.2.34]# make
[root@CentOS7-3 httpd-2.2.34]# make install

 

③ 아파치 서버를 실행하고 브라우저를 이용해서 접속 테스트를 진행한다.

[root@CentOS7-3 httpd-2.2.34]# /app/apache/bin/apachectl start
httpd: Could not reliably determine the server's fully qualified domain name, using fe80::da2f:8c5b:1b46:2ceb for ServerName

 

이런 경고 메시지가 뜨면 아래와 같이 /app/apache/conf/httpd.conf에 ServerName localhost를 추가한다.

[root@CentOS7-3 httpd-2.2.34]# vi /app/apache/conf/httpd.conf
...
ServerName localhost
...

 

아파치 서버를 다시 죽였다 살린다.

[root@CentOS7-3 httpd-2.2.34]# /app/apache/bin/apachectl stop
[root@CentOS7-3 httpd-2.2.34]# /app/apache/bin/apachectl start
[root@CentOS7-3 httpd-2.2.34]#

 

잘 실행되는 것을 확인할 수 있다.

 

step 3. PHP 설치

① PHP 설치전 컴파일을 위해 libxml 패키지 설치를 확인 후 설치한다.

[root@CentOS7-3 ~]# yum install -y libxml2*

 

이미 설치 되어있으므로 넘어간다.

[root@CentOS7-3 ~]# yum list libxml2*
Loaded plugins: fastestmirror, langpacks
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
Loading mirror speeds from cached hostfile
 * base: ftp.jaist.ac.jp
 * extras: ftp-srv2.kddilabs.jp
 * updates: ftp.iij.ad.jp
Installed Packages
libxml2.x86_64                         2.9.1-6.el7_9.6                  @updates
libxml2-devel.x86_64                   2.9.1-6.el7_9.6                  @updates
libxml2-python.x86_64                  2.9.1-6.el7_9.6                  @updates
libxml2-static.x86_64                  2.9.1-6.el7_9.6                  @updates
Available Packages
libxml2.i686                           2.9.1-6.el7_9.6                  updates
libxml2-devel.i686                     2.9.1-6.el7_9.6                  updates
libxml2-static.i686                    2.9.1-6.el7_9.6                  updates

 

② TNS_ADMIN, LD_LIBRARY_PATH와 같이 오라클 관련 경로 설정에 정의된 내용이 시스템에 존재하
는지 반드시 확인한다.

[root@CentOS7-3 local]# cd /usr/local/
[root@CentOS7-3 local]# tar xvfz php-5.6.39.tar.gz
[root@CentOS7-3 local]# cd php-5.6.39/
[root@CentOS7-3 local]# ./configure --with-apxs2=/app/apache/bin/apxs --with-oci8=instantclient,/usr/lib/oracle/19.5/client64/lib --enable-sigchild
[root@CentOS7-3 local]# make
[root@CentOS7-3 local]# make install
[root@CentOS7-3 php-5.6.39]# cp php.ini-development /usr/local/lib/php.ini
cp: overwrite `/usr/local/lib/php.ini'? y

 

step 4. Apache, PHP 설정

① /app/apache/conf/httpd.conf 파일의 내용을 수정한다. APO 서버 설정과 동일하다.

ServerName localhost // 추가 내용
.............
LoadModule php5_module modules/libphp5.so
AddType application/x-httpd-php .php .html .htm .inc // 추가 내용

 

② /usr/local/lib/php.ini 파일에 PHP 실행 환경을 설정한다. APO 서버 설정과 동일하다.

short_open_tag = On
default_charset = "UTF-8" (or "EUC-KR")
include_path=".:/usr/local/lib"
upload_tmp_dir = /tmp
date.timezone = Asia/Seoul
error_reporting = E_ALL & ~E_NOTICE

 

③ /app/apache/bin/apachectl를 열어서 다음의 내용을 추가한다.

[root@CentOS7-3 ~]# vi /app/apache/bin/apachectl
...
# oracle install
export TNS_ADMIN=/usr/lib/oracle/network/admin
export LD_LIBRARY_PATH=/usr/lib/oracle/19.5/client64/lib
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8

(또는 AMERICAN_AMERICA.KO16MSWIN949)

 

step 5. 서버 실행 후 연동 확인

① /app/apache/htdocs/index.html 파일을 다음과 같이 수정한다.

[root@CentOS7-3 ~]# vi /app/apache/htdocs/index.html
<?
 $server = "oracle";
 $user_name = "st";
 $password = "st";
 $conn=@oci_connect($user_name,$password,$server) or die('not connect:');
 echo("Oracle 19c \$conn : $conn<br>");
 $st=oci_server_version($conn);
 echo("$st<br>");
 phpinfo();
?>

 

웹페이지에서 확인한다.

 

Document Root 변경

/home/httpd/html/index.html

이때 vi /app/apache/conf/httpd.conf 에서 Document Root가 /home/httpd/html으로 되어있는지 확인한다.

 

vi /home/httpd/html/index.html

<html>
 <head>
   <title> st04 </title>
   <meta charset="UTF-8">
 </head>
 <body bgcolor="white" text="black" link="blue" vlink="purple" alink="red">
 <p>&nbsp;</p>
 <table border="1" align="center">
   <tr>
         <td width="100">
                 <p align="center">목록<br></p>
                                <p align="center"><a href="html">html</a><br></p>
                                <p align="center"><a href="python">python</a><br></p>
         </td>
    </tr>
 </table>
</html>
<br>
<?
 $server = "oracle";
 $user_name = "st";
 $password = "st";
 $conn=@oci_connect($user_name,$password,$server) or die('not connect:');
 echo("Oracle 19c \$conn : $conn<br>");
 $st=oci_server_version($conn);
 echo("$st<br>");
 phpinfo();
?>

새 모델을 생성할 때는 logical/physical을 선택한다.

 

실습 전 Model > Model Properties에 들어가 아래와 같이 설정해준다.

 

관계를 표시할 경우 아래와 같이 설정한다.

- 외래키가 일반 속성에 있을 경우 비식별관계

- primary key 있는 테이블이 부모테이블, 외래키 있는 테이블이 자식테이블

- 식별 관계 표시할 경우 부모 테이블에서 뻗어나가기

- ○ 표시는 테이블에 해당 컬럼이 없어도 되는 경우 표시

 

모델링 해보기

'모델링 공부 기록' 카테고리의 다른 글

판매 전표 모델링  (0) 2021.12.29
인사기록 모델링  (0) 2021.12.29
영수증 모델링  (0) 2021.12.24
모델링 2 - 정규화 (1차, 2차, 3차 정규화)  (0) 2021.12.19
모델링 1 - 데이터베이스 모델링  (0) 2021.12.19

▶ 단계별 정규화 과정

• 1차 정규화

: 반복그룹 속성을 추출한다. (도메인이 원자값)
 - 자식 개체가 추출되고 반드시 식별관계이다.
 - 주식별자를 가지고 나간다.
 - 자식 개체 주 식별자에 반드시 속성이 추가된다.


• 2차 정규화

: 주 식별자에 완전 기능 종속되지 않는 속성을 추출한다.
 - 자식 개체 주 식별자에 외부 식별자를 두고 나간다.
 - 부모개체가 추출되고 반드시 식별관계이다.

 

*함수적 종속

: 레코드 내에 존재하는 항목들 중에 속성 B가 속성 A에 함수적 종속관계에 있다는 것은 A를 이용 B를 식별할 수 있다는 의미

- A → B
-  A : 결정인자 (Determinant)


- A → (B,C)인 경우 A → B, A → C가 성립한다.
- (A,B) → C 인 경우 A → C, B → C는 성립하지 않는다.
- A → B , B → C인 경우 A → C가 성립될 수 있다.
   (3차 정규화 대상이 아니다.)

 

• 함수적 종속의 예
- 제품번호 → 제품명
- 학번 → (이름,학과,주소,전화번호)
- (학번,과목번호) → 점수


• 3차 정규화

: 주 식별자에 이행 종속인 속성을 추출한다.
 - 일반 속성에 외부 식별자를 두고 나간다.
 - 부모개체가 추출되고 반드시 비 식별 관계이다.

 

예시

• 비정규화

비정규화

• 1차 정규화

자식 개체가 추출되고 반드시 식별관계

주식별자를 가지고 나간다.

자식 개체 주식별자에 속성 추가

반복속성 그룹 추출한다.

주문번호만 fk이면 주문번호가 중복이 안되므로 데이터 입력이 여러개가 안된다. 
따라서 제품번호를 pk로 추가한다.

 

주문금액은 주문수량*주문단가이므로 없어도 된다.

그렇지만 서식에 있는 컬럼이므로 있는게 좋다.

 

• 2차 정규화

주식별자에 완전 종속되지 않는 것을 추출

자식 개체 주식별자에 외부식별자를 두고 나간다.

부모 개체가 추출되고 반드시 식별관계

제품 번호가 제품명을 가리킨다.

주식별자에 완전 종속되지 않는 것을 추출한다.

 

• 3차 정규화

이행 종속 속성 추출

일반속성에 외부 식별자를 두고 나간다.

부모개체 추출, 반드시 비식별관계

이행 종속 속성을 추출한다.

고객 번호는 고객명, 고객주소, 사업자번호, 수출상태를 가리킨다.

이것은 이행 종속이므로 추출한다.

 

• 관계 검증

정규화를 끝내고 마지막에 한번 더 관계를 확인한다.

위를 예시로 들면 고객 테이블에 10번이라는 고객 번호가 있다고 생각하고 주문장에 고객번호가 있어야하는지 판단한다.

- 식별관계에서는 O가 없는 경우가 있음

- 비식별관계에서는 O가 거의 반드시 있음

'모델링 공부 기록' 카테고리의 다른 글

판매 전표 모델링  (0) 2021.12.29
인사기록 모델링  (0) 2021.12.29
영수증 모델링  (0) 2021.12.24
ERwin 기본 설정  (0) 2021.12.19
모델링 1 - 데이터베이스 모델링  (0) 2021.12.19

관계형 데이터베이스

▶ 관계형 데이터베이스의 특징
• 데이터 기술
   - 데이터딕셔너리, 메타데이타, 사용자 데이터, …
 응용 프로그램과 데이터의 독립성 (프로그램에 종속된 데이터를 만들면 X)
• 데이터 구조변경이 용이
• 통합레코드의 모임
   - 데이터간의 관계 포함
   - 응용 메타 데이타 포함 – 입력 양식, 보고서
   - 인덱스
• 사용자 관점의 정보 모델

 

▶ 관계형 데이터베이스의 장점
• 독립성 강화 (*데이터가 프로그램으로부터 독립)
• 무결성 유지
• 중복 감소
• 공유 가능
• 표준화 용이
• 보안 편리

 

데이터 모델

: 업무 영역분석 단계에서 데이터와 관련된 개체 관계도를 정규화 과정을 거쳐 도식화 하는 것 

 

업무가 계속 생기기 때문에 (데이터가 계속 생기기 때문) 이 과정이 반복된다.

 

▶ 논리 모델링

 : 읽을 수 있는 형태로 생성
• 기업 조직이 필요로 하는 정보를 도출하고 도출된 정보를 체계적으로 구조화
• 시스템에서 수행 될 모든 기능이 반영된 데이터 모델을 구축
• 기업의 정보 구조를 정확하고 완전하게 구조화


▶ 물리 모델링
• 각 DBMS의 특성을 고려하여 구조화된 논리 모델을 변환
• 구축된 데이터베이스가 최적의 성능을 발휘 하도록 구현
• 적절한 분산 배치 등의 기능을 고려

 

 

외부스키마(user view) : 사용자를 분석해서 어떤 데이터를 사용하는지 확인하는 것

 *user view 개별 화면 하나가 사용자라고 보면 된다. 

 

▶ 데이터 모델의 목적  → 최적의 데이터베이스 시스템 구축

• 데이터의 품질 향상 (무결성, 확장성, 비중복성, 정확성,…)
• 연관 조직의 정보 요구에 대한 정확한 이해 제공
• 개발자, 설계자,분석가, 사용자간에 의사 소통 수단
• 신규 및 개선 시스템에 대한 기반 제공

 

▶ 데이터 중심의 개발 방법

▶ 응용 프로그램 개발과 모델링 과정과의 관계

▶ 모델링 개요

- 기업이나 조직의 정보 구조를 개체(Entity)와 관계(Relationship)를 중심으로 체계적으로 표현하고 문
서화 하는 기법
- 정보 시스템의 중심을 데이터 관점에서 접근하는 분석 방법

* Entity 내부의 모든 tuple는 구별되며 순서에 무관

'모델링 공부 기록' 카테고리의 다른 글

판매 전표 모델링  (0) 2021.12.29
인사기록 모델링  (0) 2021.12.29
영수증 모델링  (0) 2021.12.24
ERwin 기본 설정  (0) 2021.12.19
모델링 2 - 정규화 (1차, 2차, 3차 정규화)  (0) 2021.12.19

전자서명

▶ 배경
종이 문서 사회에서 정보화 사회로의 진전으로 다양한 서비스 요구
데이터 무결성 , 사용자 인증, 부인방지 서비스가 필수적

 

목적
신뢰성 확보 ( 내용의 위·변조 및 신분 확인에 사용)

전자서명 = 사용자 인증 + 메시지 인증

▶ 전자문서의 문제점
• 위,변조가 용이 : 무결성
• 문서작성 사실 입증 곤란 : 부인방지

 

▶ 전자상거래의 문제점
• 거래상대방의 신원확인 곤란 : 사용자 인증
• 전송 내용의 비밀 유지 곤란 : 기밀성

 

▶전자서명으로 알 수 있는 사항

• 서명자 신원확인(User Authentication)
  - 개인키의 소유자가 전자서명 행위자임을 증명
  - 서명자 고유의 표식

• 위조 불가(Not forgeable)
  - 합법적인 서명자 외에는 전자서명 생성 불가 증명

• 변경 불가(Unalterable)
  - 서명한 문서의 내용과 서명의 변경 불가 증명

• 부인 불가(Non-Repudiation)
- 서명은 본인 이외에는 불가능함을 증명

• 재사용 불가(Not Reuseable)
  - 다른 전자문서의 서명으로 사용 불가능함을 증명

 

암호화 방법과 전자서명

전자서명은 전자서명의 조건을 만족하면서 서명방식과 검증 방식이 명확하여야 함


▶ 대칭키 암호 알고리즘에 의한 방법
• 중재된 서명기법
• 서명과 검증을 제 3자에 의해서 행할 수 밖에 없음


▶ 공개키 암호 알고리즘에 의한 방법
• 메시지 복원형 전자서명 방식
• 문서 자체를 이용하는 서명방식
• 메시지 부가형 전자서명 방식
• 문서에 서명메세지를 포함하는 방식

 

공개키 이용 전자서명

공개키 : A의 인감 증명서

개인키 : A의 인감

* 전자서명 : A의 개인크로 데이터의 전자서명 생성, A의 공개키로 전자서명 검증

- 평문(메시지 다이제스트) + 개인키 = 암호문(전자서명)

- 암호문(전자서명) + 공개키 = 평문(다이제스트)

1. 송신자는 보낼 메시지를 해시함수로 다이제스트를 생성한다.

2. 다이제스트와 송신자의 개인키로 암호화한다.

3. 메시지와 서명을 같이 송신한다.

4. 수신받은 서명을 송신자의 공개키로 복호화해 다이제스트를 생성한다.

5. 수신받은 메시지를 해시함수를 통해 다이제스트를 생성한다.

6. 서명을 복호화해 얻은 다이제스트와 메시지를 해시함수를 통해 얻은 다이제스트를 비교한다.

   → 비교해서 같으면 신뢰할 수 있고, 다르면 거래의 신뢰성을 확보할 수 없다.

 

※ 사용자와 메시지 인증은 가능하지만 기밀성 보장이 안된다.

※ 개인키를 잃어버리면 자신이 책임져야 한다.

 

전자서명의 이용 : 전자봉투 (원타임 비밀키)

1. 송신자는 메시지와 암호화하기 위해 난수를 발생해 비밀키를 생성한다.

2. 메시지를 비밀키로 암호화해 암호메시지를 만든다.

3. 비밀키를 수신자의 공개키로 암호화한다.

4. 암호메시지와 공개키로 암호화한 비밀키를 디지털봉투에 담아 전송한다.

5. 수신자는 디지털 봉투에 있는 암호화된 비밀키를 수신자의 개인키로 복호화해 비밀키를 얻는다.

6. 암호화된 메시지를 비밀키로 복호화한다.

 

※ 사용할 때마다 난수를 발생시켜 비밀키로 정한다. 받는 사람의 공개키로 이 비밀키를 암호화한다. 

※ 기밀성이 가능하지만 인증은 불가능하다.

※ 네트워크에서 빠르게 사용 가능하다.

 

공개키와 대칭키를 이용한 전자서명

공개키를 이용한 전자서명으로 사용자 인증이 가능하다.

대칭키를 이용한 전자서명으로 기밀성이 가능하다.

※ 인증과 기밀성이 가능하다.

 

▶ PKI(Public Key Infrastricture) 구성 요소

- 공개키 소유자 증명

- 인증서는 인감증명서에 해당한다. → 기밀성, 무결성, 인증

인증서

 

▶ 인증서의 정의

- 공개키 소유자 증명

- 인증서라 함은 개인키와 이에 합치하는 공개키에 대하여 이를 소유하는 자연인 또는 법인과의 귀속관계 등을 인증기관이 자신의 개인키로 전자서명하여 확인, 증명하는 전자적 정보

▶ 인증서 : X.509

• 1K바이트 정도의 바이너리 데이터
• RFC 2459(X.509 ver. 3)

 

인증서 항목
• 서명전 인증서
  - tbsCertificate(to be signed certificate)
  - 확장항목 이외의 항목 필수
• 서명 알고리즘
  - 메시지 다이제스트 알고리즘(MD2,MD5..)
  - 공개키 암호 알고리즘
• 인증기관
  - 서명전 인증서 부분을 입력으로 해서 서명
  - 인증기관의 개인키와 인증서로 기재한 알고리즘 이용

 

▶ 인증서 발행과 이용

인증서를 발행하기 위해서는 공개키의 소유주는 인증기관에 공개키를 등록하고 인증기관은 등록된 개인의 공개키를 자신의 개인키로 서명해서 인증서를 발행한다.

▶ 인증 기관과 CRL

• CA (Certificate Authority) : 인증서 발행기관
• RA (Registration Authorities) : 인증서 유저 등록 기관

 

 

• CRL (Certificate Revocation List) : 인증서 폐지 목록

키 관리

비밀키 분배의 어려움

▶ 물리적인 방법으로 전달
 • 링크 암호화에서 적용 가능
 • 단대단 암호화에서 적용 어려움


▶ 이전의 키를 사용하여 암호화된 새로운 키를 전송
 • 링크 암호화나 단대단 암호화 모두 적용 가능
 • 공격자가 어떤 한 키를 안다면 이후의 모든 키가 노출


▶ 제 3자(키 분배 센터)를 통하여 키 분배
 • 단대단 암호화에서 널리 채택
 • 사용자는 키 분배 센터와 유일한 키를 공유

 

▶ KDC를 이용한 키분배 방법 (Kerboros)

전제조건

각 사용자 A, B는 KDC에서 분배한 마스터 키 1개씩 소유하고 있다.

 

1. Request || ID(A), A, B

- 발신자 A는 응답자 B와 통신하기위해 KDC에 Request 보낸다. 

- 요청에는 자신의 신원정보 ID(A)와 B와 통신할 세션키를 요청한다. (*세션키=비밀키)

 

2.Eka[SK, ID(B), T]

- KDC는 발신자 A에게 B와 통신할 세션키, B의 신원정보 ID(B), 난수(T)를 응답한다. 

- 응답시 KDC는 A의 마스터키로 암호화해 A에게 보낸다. (KDC는 A, B의 마스터키를 가지고 있다.)

 

2. Ekb[SK, ID(A), T]

- KDC는 발신자 B에게 세션키와 A의 신원정보 ID(A), 난수(T)를 B의 마스터 키로 암호화해서 보낸다.

 

3. Esk[ID(A), T]

- A가 자신의 신원정보 ID(A)와 난수 (T)를 세션키로 암호화해서 B에게 전송한다.

- B는 A의 난수(T)와 A의 신원정보 ID(A)를 통해 A의 신원을 확인한다.

 

4. Esk[ID(B), T+1]

- B는 자신의 신원정보 ID(B)와 난수(T+1)를 연산하여 세션키로 암호화해 A에게 전송한다.

- A는 난수(T+1)에 연산된 것을 확인해 B의 신원을 확인한다.

 

통신 종료

- 통신이 종료되면 발급받은 세션키는 폐기된다.

- 다시 통신하려면 세션키를 KDC에 요청한다.

 

▶ 공개키 기관에 의한 세션키 분배 (SESAME) 

전제 조건

- A는 자신의 공개키(KUa)와 개인키(KRa)를 각각 소유한다.

  A는 공개키 기관에 자신의 공개키(KUa)를 등록한다.

  공개키 기관은 공개키 기관의 공개키인 (KUau)를 나눠준다.

- B는 자신의 공개키(KUb)와 개인키(KRb)를 각각 소유한다.

  B는 공개키 기관에 자신의 공개키 (KUb)를 등록한다.

  공개키 가관은 공개키 기관의 공개키인 (KUau)를 나눠준다.

 

1. Request || Time1

- A가 B와 통신하기 위해 B의 공개키를 공개키 기관에 요청한다.

- 이때 Request를 구분하기 위한 난수(Time1)를 같이 보낸다. (공개키 기관인지 알기 위해)

 

2. E(KRau)[KUb||Request||Time1]

- 공개키 가관은 요청 메시지와 공개키 기관에 등록된 B의 공개키(KUb)를 공개키 기관의 개인키 (KRau)로 암호화해 A에게 응답한다.  -  A는 공개키 기관이 보낸 것을 공개키 기관의 공개키(KUau)로 복호화해 확인하여 B의 공개키 (KUb)를 얻는다.

→ A는 B의 공개키를 얻게 된다.

 

3. E(KUb)[ID(A)||N1]

- A가 자신의 신원정보 ID(A)와 N1(난수)를 B의 공개키(KUb)로 암호화해 B에게 전송한다.

  (ID(A): 자신이 누군지 알리기 위함 / N1: B인지 확인하기 위함)

- A가 B의 공개키로 암호화하여 전송한 것을 B가 개인키로 복호화하기에 기밀성이 보장된다.

 

4. Request||Time2

B는 자신의 개인키로 복호화하고 A의 공개키가 없으므로 공개키 기관에 Time2와 함께 요청한다.

 

5. E(KRau)[KUa||Request||Time2]

- 공개키 기관은 요청 메시지와 A의 공개키를 공개키 기관의 개인키로 암호화해 응답한다.

- 공개키 기관이 공개키 기관의 개인키(E(KRau))로 암호화하여 전송한 것을 B가 공개키 기관의 공개키로 복호화해 A의 공개키라는 것을 확인하고 얻는다.

→ B는 A의 공개키를 얻게 된다.

 

6. E(KUa)[N1||N2]

- B는 N1, N2 난수를 A의 공개키(KUa)로 암호화하여 전송한다. 

  (N1: B인것을 확인하기 위해 A가 전송, N2: A인지 확인하기 위해 B가 전송)

- B가 A의 공개키로 암호화하여 전송한 것을 A가 개인키로 복호화해 기밀성이 보장된다.

 

7. E(KUb)[N2]

- A는 N2라는 응답을 보내 자신이 A라고 응답한다.

- A가 B의 공개키로 암호화하혀 전송한 것을 B가 자신의 개인키로 복호화해 기밀성이 보장된다.

 

8. E(KUb)[E(KRa)[Ks]]

- A는 세션키(Ks)를 자신의 개인키로 암호화해 B의 공개키로 암호화하여 B에게 전송한다.

- B는 자신의 개인키로 복호화하고 A의 공개키로 복호화해 세션키를 획득한다. (기밀성 보장)

 

통신 종료

- 통신이 종료되면 세션키는 버려진다.

- 다시 통신하려면 8번 과정이 진행된다. (1-7 과정 진행X)

- A, B는 서로 공개키 기관으로부터 받은 안전한 공개키를 소유하고 있다고 생각하기 때문이다.


해시함수

- 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는 함수

- 메시지 인증 코드에 대한 변형

- 메지시의 모든 비트들에 대한 함수

- 임의의 길이(M)을취해 정해진 크기 h의 메시지 Digest를 만드는 일방향 함수

- 해시의 목적 : 무결성 확보

▶ 해시함수의 요구조건

• 어떤 크기의 메시지 M에도 적용 가능
• H는 고정된 크기의 hash code를 만듦
• H(M)은 어떤 주어진 M에 대해서도 계산하는 것이 쉽다. (해시함수는 비밀키 암호 시스템보다 빠름
• 주어진 hash code h에 대해, H(M) = h인 M을 찾는 것이 계산적으로 실행불가능(one-way)

  → 해시코드 사용 이유: 계산방법이 없고 무작위로 대입하기때문(생일공격)
• 어떤 주어진 블록 M에 대해서, H(M’) = H(M) 인 M과 M’가서로 다른 것을 찾는 것이 계산적으로 실행 불가능
• H(M’) = H(M)인 어떤 (M, M’) 쌍을 찾는 것이 계산적으로 실행 불가능(collision-free)

 

 

단순 해시 함수

: 메시지를 n 비트 블록으로 m개로 나누어 블록끼리 XOR하여 출력되는 블록을 해쉬로 함

▶ 해시함수의 종류

 

오라클 접속 환경과 PHP 접속하기

 

 

인스턴스 : 메모리에 있는 논리적 구조

데이터베이스 : 하드드라이브에 있는 구성요소

 

접속 식별자 tnsnames.ora

oracle =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = tcp)(HOST = 192.168.10.135)(port = 1521))
      (CONNECT_DATA = (SID = DB19))
    )

ora =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = tcp)(HOST = 192.168.10.138)(port = 1521))
      (CONNECT_DATA = (SID = DB19))
    )

dal =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = tcp)(HOST = 192.168.10.11)(port = 1521))
      (CONNECT_DATA = (SID = DB19))
    )

 

Oracle 접속 : oconn.php

<?
  $server = "oracle";
  $user_name = "st04";
  $password = "st04";
  $conn=@oci_connect($user_name, $password, $server) or die('Could not connect:');
  echo("Oracle 19c \$conn : $conn<br>");
  $st=oci_server_version($conn);
  echo("$st<br>");
?>

 

또는 아래와 같이 직접 ip주소를 쳐서 사용할 수도 있다.

 

<?
  $server = "(DESCRIPTION =
    (ADDRESS = (PROTOCOL = tcp)(HOST = 192.168.10.11)(port = 1521))
    (CONNECT_DATA = (SID = DB19))
  )";
  $user_name = "st04";
  $password = "st04";
  $conn=@oci_connect($user_name, $password, $server) or die('Could not connect:');
  echo("Oracle 19c \$conn : $conn<br>");
  $st=oci_server_version($conn);
  echo("$st<br>");
?>

여기 @ 는 클라이언트에게 오류내용을 보여주지 않기 위해서 

 

공개키 알고리즘
• 두 개의 다른 키 사용


공개키 : 모든 사람이 접근 가능한 키 (공개)

개인키 : 각 사용자 자신만이 소유 (비밀)


관용 암호에 사용되는 키는 비밀키라고 함


공개키 알고리즘의 특징
• 암호 알고리즘과 암호키를 알아도 복호키 계산 불가능
• 두 개의 키 중 하나는 암호에 다른 하나는 복호에 사용

 

1. 공개키와 개인키 생성
2. 공개키는 공개하고 개인키는 개인이 소유
3. A는 B의 공개키로 메시지를 암호화
4. B는 자신의 개인키로 메시지 복호화
(B의 개인키를 모르는 제 3자는 메시지 복호 불가능)

 

- 암호 사양
  암호알고리즘 : mod 7에서 곱셈
  공개키 : 3, 개인키 : 5
  원문 : 4

- 암호화
 4 * (3 mod 7) = 5 (암호문)

- 복호화
 5 * (5 mod 7) = 4 (원문)

>> mod 7 에서 3, 5는 서로 역원 (mod에서는 정수 내에 곱셈에 대한 역원이 존재한다.)

 

mod 소수에서는 잉여계가 다 나온다.

 

원문 : WE WISH YOU A MERRY CHRISTMAS AND A HAPPY NEW YEAR
 W E  W  I  S  H  Y  O  U  A  M  E  R  R  Y  C  H  R  I  S  T  M  A  S  A  N  D  A  H  A  P  P  Y  N  E  W  Y  E  A  R
23 5  23 9  19 8  25 15 21 1  13 5  18 18 25 3  8  18 9  19 20 13 1  19 1  14 4  1  8  1  16 16 25 14 5  23 25 5  1  18
4  25 4  8  21 3  14 1  31 5  28 25 16 16 14 15 3  16 8  21 26 28 5  21 5  33 20 5  3  5  6  6  14 33 25 4  14 25 5  16
D  Y  D  H  U  C  N  A  %  E  @  Y  P  P  N  O  C  P  H  U  Z  @  E  U  E  &  T  E  C  E  F  F  N  &  Y  D  N  Y  E  P
^암호

개인키 : 5
공개키 : 15

암호화 : (개인키*원문 키맵매칭 값) mod 37 = 암호문 값

암호 알고리즘 : mod37 에서 곱셈
공개키 : 15
키맵
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
0 A B C D E F G H I J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  !  @  #  $  %  ^  &  *  (  )

서명문 : DYDHUCNA%E@YPPNOCPHUZ@EUE&TECEFFN&YDNYEP

복호화 : (공개키*암호문 키맵매칭 값) mod 37 = 원문 값

 

▶ 공개키 암호의 기밀성

▶ 공개키를 이용한 인증 (부인 방지)

- 기밀 통신시 공개키로 암호화한다.

- 사용자 인증시 개인키로 암호화한다.

 

▶ 공개키를 이용한 기밀통신과 서명

▶ 공개키 암호 시스템의 사용
• 암호/복호 (수신자의 공개키로 메시지 암호)
• 디지털 서명 (송신자의 개인키로 메시지 서명)
• 키 교환 (세션키를 교환하기 위해 사용)

▶ 공개키 암호는 수학적인 난제를 이용 암호화를 수행한다.


▶ 소인수 분해의 어려움
• RSA


▶ 이산대수문제
• 엘가말(El Gamal)
• 디퍼헬만(Diffie-Hellman)
• 타원 곡선 (Elliptic Curve)

 

▶ 공개키 알고리즘의 조건 (Diffie와 Hellman)
• 키 쌍(공개키 KU, 개인키 KR)의 생성이 쉽다.
• 다음 식과 같은 암호문의 생성이 쉽다.

• 다음식과 같은 암호문의 복구화가 쉽다.

• 공개키 KUb로부터 개인키 KRb를 결정하는 것은 어렵다.
• 공개키 KUb와 암호문 C로부터 메시지 M의 복구가 어렵다.
• 암호와 복호 기능이 다음과 같이 적용 가능하다. (추가 사항)

 

▶ 공격 유형
• 전사적 공격에 취약
  → 키의 크기를 크게 함으로써 방지
(상대적으로 속도가 느려짐)
• 공개키로부터 개인키를 계산하는 방법
  → 수학적으로 계산이 불가능함을 증명하지 못함
• 가능한 메시지 공격
: 모든 가능한 메시지를 공개키로 암호화하여 암호문과 비교
  → 메시지에 임의의 비트를 추가함으로써 방지

 

▶ RSA의 개발
: 1977년에 개발되어 1978년에 공포 (Rivest, Shamir, Adleman)


▶ 알고리즘
• 평문은 블록으로 암호화
• 암호화

• 복호화

공개키 : KU = {e, n}, 개인키 : KR = { d, n }

 

▶ e,d,n 값 생성
• p, q 선택 : p와 q는 10¹ 정도의 소수
• n = p * q
• e : GCD(e, ф(n)) = 1인 값을 선택
• d : e * d = 1 mod ф(n) 인 값을 계산

 

▶ 복호화 과정의 증명

 

+ Recent posts