[데이터베이스] 무결성, 보안

📂 무결성(Integrity)

데이터베이스에서 무결성(Integrity)이란,

데이터의 정확성 또는 유효성

을 의미한다. 

하지만, 동적으로 변화하는 DB 환경 하에서 데이터의 정확성을 유지한다는 것은 상당히 어려운 일이다. 그렇기 때문에 실제로는 어떤 무결성 규칙(Integrity Rule)을 정해 놓고 이것에 위배되지 않는 한 DB의 무결성은 유지되는 것으로 간주한다. 

 

무결성 규칙에는 다음과 같은 것들이 있다.

🏷 도메인 무결성 규칙(Domain Integrity Rules)

주어진 애트리뷰트의 값이 그 애트리뷰트가 정의된 도메인에 속한 값이어야 한다는 것을 규정하는 것이다. 

예를 들어, 전화번호 애트리뷰트의 경우 일반적으로 '010-1234-4567'와 같은 형태로 숫자와 '-'로만 구성될 수 있다고 규정해 놓으면 '010-1234-87R0'과 같은 형태는 이 무결성 규칙에 위배되어 삽입될 수가 없다. 

🏷 릴레이션 무결성 규칙(Relation Integrity Rules)

어느 한 튜플이 릴레이션에 삽입 가능한가 또는 한 릴레이션과 또 다른 릴레이션 튜플들 간의 관계가 적절한가를 규정해 놓은 것이다. 

예를 들어, 수강 릴레이션의 학번 애트리뷰트는 학생 릴레이션의 기본키인 학번을 가리키는 외래키이다. 따라서 수강 릴레이션의 학번은 학생 릴레이션의 학번에 없는 값을 삽입할 수가 없다. 

📄 SQL에서 무결성 규칙을 정의하는 방법

SQL에서는 무결성 규칙을 제약조건으로 정의할 수 있다. 다음과 같이 크게 3가지로 나눌 수 있다.

🏷 애트리뷰트 제약조건

애트리뷰트 제약조건을 생성하기 위한 SQL 구문은 다음과 같다.

[CONSTRAINT constraint_name] CHECK (cond-exp)

여기서 constraint_name은 제약조건의 이름이며, cond-exp는 제약조건을 의미한다. 

예를 들어, 애트리뷰트 봉급이 6000000보다 작아야 한다면 다음과 같이 정의될 수 있다.

CREATE TABLE employee(
    이름 CHAR(10),
    봉급 INTEGER CHECK(봉급<6000000)
);

🏷 기본 테이블 제약조건

기본 테이블을 정의할 때 관련 제약조건은 다음과 같은 SQL 구문으로 명시할 수 있다.

CREATE TABLE enroll(
    sno INTEGER NOT NULL,
    code CHAR(4) NOT NULL,
    score INTEGER NOT NULL,
    PRIMARY KEY(sno, code),
    FOREIGN KEY(sno) REFERENCES student(sno)
            ON DELETE CASCADE
            ON UPDATE CASCADE,
    FOREIGN KEY(code) REFERENCES course(code)
            ON DELETE CASCADE
            ON UPDATE CASCADE,
    CHECK (score >= 0 AND score <= 100)
);

enroll 테이블에는 학번과 과목코드로 기본키가 설정되어 있고 이 기본키에는 NULL 값을 가질 수 없다. 또한, 학번과 과목코드는 각각 학생과 과목 테이블의 외래키로 이들 키는 참조 무결성 제약조건이 적용된다. 성적은 CHECK로 제약조건이 규정되어 있다.

🏷 주장(Assertion)

제약조건을 위반하는 연산이 수행되지 않도록 하는 것이다. 불필요한 assertion은 DROP문을 사용하여 삭제할 수 있다.

CREATE ASSERTION 이름 CHECK (조건식);
DROP ASSERTION 이름;

에를 들면, "모든 과목의 학점은 최소 1학점 이상이어야 한다." 와 "모든 과목의 학점은 4학점 이하여야 한다."라는 assertion은 다음과 같이 표현된다.

CREATE ASSERTION MIN_CREDIT
    CHECK    ((SELECT MIN(course.credit)
               FROM course) > 0);
               
CREATE ASSERTION MAX_CREDIT
    CHECK    ( NOT EXISTS (SELECT *
               FROM course
               WHERE NOT (course.credit < 5) ) );

Assertion은 데이터베이스가 항상 만족하기를 바라는 조건을 직접적으로 표현하는 프레디킷이다. DBMS는 assertion의 프레디킷을 검사해 참이면 assertion을 위배하지 않는 경우이므로 DB의 수정을 허용한다. 

📄 트리거(Trigger)

위의 선언적 형태의 무결성 규칙을 위반하면 기본적으로 그 트랜잭션을 취소시키면 된다. 그러나 이런 취소 이외의 별다른 조치가 필요할 경우 트리거 기법을 이용한다.

 

트리거는 테이블에 무슨 일이 일어나면 자동으로 실행된다. 즉, 트리거란 테이블에 삽입, 수정, 삭제 등의 작업이 발생할 때에 자동으로 작동되는 개체이다.

트리거는 테이블에 이벤트가 발생하면 자동으로 부착된 트리거가 실행된다. 트리거의 작동은 Stored Procedure와 비슷하지만 직접 실행시킬 수 없고 오직 해당 테이블에 이벤트가 발생할 경우에만 실행된다. 그리고 Stored Procedure와 달리 IN, OUT 매개변수를 사용할 수 없다

 

트리거를 요약하여 정리하면 다음과 같다.

  • 데이터를 변경할 때마다 실행되는 특별한 저장 프로시저이다. 
  • 한 테이블과 연관된다. 
  • 삽입, 삭제, 수정 시 자동적으로 실행된다.
  • Stored Procedure와 달리 직접 호출될 수 없다. 
  • 하나의 트랜잭션이다

트리거 사용의 이점은 다음과 같다. 

  • 데이터베이스 내 관련 테이블들 간의 순차적 변경이 가능하다. 
  • CHECK보다 더 복잡한 데이터 무결성을 강화할 수 있다. 
  • 사용자 정의 에러 메시지를 정의할 수 있다. 
  • 비 정규화된 데이터베이스 환경에서도 사용될 수 있다.
  • 변경 시 데이터의 전후 상태가 비교 가능하다. 

트리거 사용 시 고려해야 할 사항은 다음과 같다.

  • 트리거는 실행 후에 작동되고, 제약조건은 실행 전에 수행된다. 
  • 테이블은 어떤 동작에 대해 여러 개의 트리거를 가질 수 있다.
  • 테이블 소유자만이 트리거를 생성, 제거할 수 있다.
  • 트리거는 결과 세트를 리턴할 수 없다.
  • 트리거는 다중 행 동작을 처리할 수 있다(여러 행에 영향을 미친다).

 

트리거의 명세 방법은 표준 SQL에는 정의되어 있지 않으나 대부분 DBMS는 다음과 같이 SQL을 확장해 트리거 정의문을 제공하고 있다.

한 예시를 살펴보면 다음과 같다.

CREATE TRIGGER STUDENT_INS
      AFTER INSERT ON student
BEGIN UPDATE 학과테이블
      SET 학생수 = 학생수 + 1
      WHERE 학과코드 = NEW_STUDENT.학과코드;
END;

📂 보안

데이터베이스 보안(Database Security)이란, 권한이 없는 데이터 엑세스, 악의적인 데이터 파괴 및 유출로부터 데이터베이스를 보호하는 것을 말한다. 데이터를 사용할 수 있는 사용자마다 계정과 비밀번호를 부여하고 데이터베이스의 특정 부분에 특정 작업만을 허용할 수 있도록 관리되도록 한다.

 

이와 관련하여 DBMS는 다음의 두 가지 기능을 제공하고 있다.

  1. DBMS는 데이터베이스에 대한 접근을 통제할 수 있는 기능을 제공하는데, 이를 접근 제어(Access Control)라 한다. DBMS는 접근 과정을 통제하기 위해 사용자 계정과 암호를 관리한다. 
  2. DBMS는 특정 사용자에게 지정된 데이터베이스 영역만 접근할 수 있고 그 외에는 접근할 수 없도록 통제하는 기능을 제공해야 한다. 이런 목적을 위해 권한 관리 모듈을 가지고 있다. 

데이터베이스 관리자(DBA)는 데이터베이스 시스템 전체에 대한 보안을 관리하며 이를 위한 모든 권한을 가지고 있다. 

 

DBMS에서 사용되는 일반적인 데이터베이스 보안 기법으로는 다음과 같은 것들이 있다. 

📄 권한 부여 테이블 사용

데이터베이스를 접근하는 각 사용자에 대해서는 그 사용자가 접근할 수 있도록 권한이 부여된 데이터 객체이 데이터 객체에 대해 수행시킬 수 있는 연산에 관한 정보를 가진 테이블이 있어야 한다. 이를 사용자 프로파일(User Profile)이라 한다. DBMS에서는 모든 사용자에 대한 프로파일을 하나의 테이블로 종합 관리해서 보관하고 있는데 이것을 권한 부여 테이블(Authorization table)이라 한다. 

이 테이블 엔트리 T[i, j]는 데이터 객체 j에 대해 사용자 i가 수행할 수 있는 연산 권한을 표현하고 있다.

📄 뷰 기법

뷰(View)의 정의 그 자체가 권한 부여 기법이 될 수 있다. 

예를 들어 , 학생 릴레이션의 생성자 A가 다른 사용자 B에게 학생 릴레이션의 일부 튜플이나 속성에 대해서만 접근할 수 있게 하려면 다음과 같은 '학생_뷰'를 정의하여 사용자 B에게 권한을 부여하면 된다. 

CREATE VIEW 학생_뷰
    AS     SELECT sno, sname, sdept
           FROM student
           WHERE sdept = '컴퓨터';

뷰 기법은 보안 기법 중에서 가장 간단하고 쉽게 적용할 수 있는 방법이다. 보안에 민감한 데이터를 권한이 없는 사용자로부터 은닉시킬 수 있다. 하지만, 갱신, 삽입, 삭제와 같은 연산에 제약이 있다. 

📄 GRANT/REVOKE 기법

위의 뷰 기법은 허용된 데이터에 대해 연산을 제한할 수 있는 방법은 아니다

특정 데이터와 연산을 특정 사용자만이 수행할 수 있게 권한 부여를 명세할 수 있는 GRANT/REVOKE 명령어가 있다. 

 

데이터베이스 시스템에서 릴레이션 생성자그 테이블에 대한 모든 권한을 갖는다. 또한 DBA는 DBMS에 있는 모든 자원에 대해 접근할 수 있는 권한을 가지고 있다. 따라서 릴레이션 생성자나 DBA는 자신의 권한을 GRANT문을 사용해 그 권한의 일부를 다른 사용자에게 다시 부여해 줄 수 있다. GRANT SQL 명령문의 구조는 다음과 같다. 

GRANT 권한_리스트 ON 객체 TO 사용자 [WITH GRANT OPTION];

사용자는 GRANT 절에 SELECT, INSERT, DELETE, UPDATE 중 한 개 이상의 권한을 포함할 수 있다. 여기서 WITH GRANT OPTION을 같이 쓰게 되면 권한을 부여받은 B 사용자도 다른 사용자에게 자기가 부여받은 권한을 또다시 부여할 수 있다.

 

제 3자에게 부여한 권한을 회수할 때는 REVOKE 명령문을 사용한다. 

REVOKE [GRANT OPTION FOR] 권한_리스트 ON 객체
      FROM 사용자 {CASCADE, RESTRICT};

여기서 만약 GRANT OPTION FOR가 사용되면 접근 권한을 취소하는 것이 아니라 다른 사용자에게 권한을 부여할 수 있게 한 권한 자체를 취소하는 것이다. 

 

이를 예를 들어 설명하면 다음과 같다.

#생성자
GRANT SELECT, INSERT ON student TO A;
GRANT SELECT ON student TO B WITH GRANT OPTION;

#사용자 B
GRANT SELECT ON student TO C;

#생성자
REVOKE SELECT ON student FROM B CASCADE;

먼저 생성자가 A에게 학생 릴레이션에 대한 검색과 삽입 권한을 부여한다. 여기서 GRANT OPTION이 없기 때문에 A는 다른 사용자에게 권한을 부여할 수 없다. B에게는 GRANT OPTION을 사용했기 때문에 다른 사용자에게 권한을 부여할 수 있고, 이를 실제로 C에게 부여하였다. 마지막으로 B에게 준 검색 권한을 회수한다. 이 권한 취소는 CASCADE에 따라 자동적으로 파급되므로 B가 C에게 부여한 권한이 C가 다른 사용자로부터 이 권한을 이중으로 부여받지 않는 한 자동으로 취소된다. 결과적으로 A에 첫 번째로 부여한 권한만 남게 된다.

📄 데이터 암호화 기법

데이터 암호화(Data Encryption)는 허가받지 않은 사람들이 내용을 쉽게 이해할 수 없도록 은폐시키기 위해 데이터를 암호로 바꾸는 것이다. 

암호 시스템(cipher system)은 암호화 알고리즘(E: encryption), 암호화 키(K: encryption Key), 해독 알고리즘(D: decryption)으로 구성된다. 전송이나 저장해야 될 원시 데이터평문(P: plaintext)이라 하고 암호화된 결과암호문(C: ciphertext)이라 할 때 암호 시스템 구성은 다음과 같다. $$C = E^K(P)$$ $$P = D^K(C)$$

 

데이터 암호화 기법은 설계자의 보안 정책에 따라 다양하게 구현될 수 있다.

🏷 전치 암호화 기법

문자들을 일정한 간격으로 나누고 위치를 변경시키는 것이다. 

 - 평문 : ENCRYPTION ALGORITHM

 - 암호문 : NERCPRITNOA#GLROTIMH

위 내용은 데이터를 두 문자씩 나누고, 다시 그 문자를 서로 교환하는 방법이다. 단어 사이의 공백도 하나의 문자로 취급하기 때문에 #으로 표시하였다. 

🏷 대체 암호화 기법

평문의 문자를 다른 문자로 대체하는 방법이다. 

- 평문 : THIS TEXT IS TOP SECRET

- 암호화 키 : TODAY

 

이를 암호화하는 단계는 다음과 같다.

  1. 평문을 암호화 키와 같은 길이의 블록으로 나눈다. 이때 단어 사이의 공백은 #으로 채운다. 
    THIS# TEXT# IS#TO P#SEC RET##
  2. 대체할 문자 코드를 #=00, A=01, B=02 ... Z=26으로 정하고 각 문자를 해당 정수 코드로 대체한다.
    2008091900 2005242000 0919002015 1600190503 1805200000
  3. 암호화 키에 대해서도 2단계와 같은 방법으로 변환 시킨다. 
    암호화 키 = 2015040125
  4. 평문의 각 블록에 대해 암호화 키에 대응 문자의 정수들을 문자 별로 합산한 뒤, MOD 27을 적용한다. 
  5. 합산 결과를 정수 코드에 해당하는 문자로 바꾸어 암호문을 얻는다.
    암호문 = MWMTY MTAUY BGDUG IOWFA KTXAY

4단계

🏷 DES 기법

미국 정부가 일반 대중이 사용할 수 있도록 개발한 암호화 기법으로, 대체 암호화 기법순열을 사용한다.

🏷 공개키 암호화 기법

이 암호화 방법은 암호화 키, 해독 키 두 개의 키를 사용한다. 

암호화 키공개해서 누구든 평문을 암호문으로 만들 수 있지만, 해독 알고리즘과 해독 키비밀로 유지된다.