Theory/Cipher protocol

RSA를 이용한 전자서명(디지털서명) 구현

D4tai1 2019. 5. 31.

1. RSA를 이용한 전자서명(디지털서명)

(1) RSA 전자서명 알고리즘

▶ 예전에 정리한 내용이 있어서 아래 URL을 통해 확인이 가능하다.

▶ 참고 : https://ccurity.tistory.com/93

 

(2) 전자서명(디지털서명)의 방법 

 [1] 메세지 전체에 서명 

  ▶ 메모리 비용이 많이 든다.

 [2] 인증자(authenticator)에 대한 서명

  ▶ 작은 비트블록인 인증자에 서명을 할 경우 인증자 변경 없이 문서만 변경하는 것은 불가능하다.

  ▶ 인증자 부분만 서명을 하기 때문에 기밀성은 보장할 수 없다.

 [3] 메세지의 해시값에 서명

  ▶ 해시와 해시를 암호화 한 것을 공개키로 풀어서 비교가 가능하다.

 

 

※ Hmac을 사용하면 안되는 이유는?

▶ 키를 공통으로 쓰기 때문에 중간에 변경하고 다시 암호화해서 전송하면 의미가 없기 때문이다.

▶ 즉, 중간에서 얼마든지 변조될 수 있다.

▶ 중간자 공격을 이용하면 디지털서명도 해커가 개인키와 공개키 세트를 새로 만들어 사용자에게 전송하면 위험할 수 있다.

▶ 그래서 제 3자(믿을 수 있는 인증기관)를 통해 정말 그 사람의 공개키가 맞는지 인증하는 것이 공인인증서이다.

▶ 공인인증서에는 공개키와 공개키가 맞다는 제 3보증기관의 디지털서명(보증기관의 개인키로)이 포함되어 있다.

 

※ 메세지인증과 디지털서명 중 부인방지가 가능한 것은?

▶ MAC값을 계산할 수 있는 키(대칭키)는 송신자와 수신자가 모두 가지고 있다.

▶ 서로 자기가 계산하지 않았다고 주장하기 때문에 부인이 가능하다.

 

▶ 그러나 디지털서명은 서명을 작성할 수 있는 키(개인키)는 송신자만 가지고 있다.

▶ 즉, 송신자만이 서명을 할 수 있기 때문에 서명을 내가 하지 않았다고 주장할 수 없다.

 

※ 공개키 인증서

▶ 공개키에 디지털서명을 추가한 것을 말한다.

 

(3) 전자서명

 [1] 소스

from Crypto.PublicKey import RSA from Crypto.Hash import SHA256  def main():     # 전자서명은 내 private_key로 sign(서명)     # 내 public_key로 verify(검증)      fin = open('private_key.pem', 'rb')     private_key = RSA.importKey(fin.read())     fin.close()      msg = b'I love you'     h = SHA256.new(msg).digest()     # 내가 받은 메세지의 해시를 추출      sign = private_key.sign(h, '')     # 해시를 개인키로 전자서명      print('1. hash : {}'.format(h))     print('2. sign : {}'.format(sign))      my_msg = msg     my_sign = sign     # 메세지와 해시의 사본을 생성      my_h = SHA256.new(my_msg).digest()     # my_msg의 해시를 구함      fin = open('public_key.pem', 'rb')     public_key = RSA.importKey(fin.read())     fin.close()      if public_key.verify(my_h,my_sign):         #전자서명이 붙어있는 해시와 내가 문자열에서 추출한 해시가 같은지         # ms_msg의 해시와 해시로 서명한 내용이 같은지 비교         print('verify!!')     else:         print('Denied!!')  if __name__ == '__main__':     main() 

 

 [2] 시연

 

 

(4) pickle

▶ python3 내 pickle모듈이 있다.

▶ 이 모듈은 메모리 내에 저장된 객체를 문자열로 바꾼다음 저장할 수 있다.

 [1] 시리얼라이즈

  ▶ 메모리에 존재하는 객체

 [2] 디시리얼라이즈

  ▶ 죽어있는 정보를 메모리에 올리는 것

 [3] pickle을 사용하는 이유?

  ▶ 메모리 안에 있는 객체의 정보를 파일에 저장했다가 다시 메모리에 올릴 수 있다.

 

 [4] 소스

import pickle  def main():     # 시리얼라이즈 하는 방법     a = (1, 2, 3, 4)     print(a)      pickle.dump(a, open('test.txt', 'wb+'))      # 디시얼라이즈 하는 방법     b = pickle.load(open('test.txt', 'rb'))     print(b)  if __name__ == '__main__':     main() 

 

 [5] 시연

 

 

(5) pickle을 이용한 전자서명

 [1] 소스

from Crypto.PublicKey import RSA from Crypto.Hash import SHA256  def main():     msg = b'I love you'      private_key = RSA.importKey(open('private_key.pem', 'rb').read())     # 개인키를 읽어와서 추가한다.      h = SHA256.new(msg).digest()     # msg에 대한 해시를 구한다.      sign = private_key.sign(h, '')      # 해시로 서명을 한다.      pickle.dump(sign, open('my.sign', 'wb+'))     # sign한 것(객체)를 파일로 저장한다.      # 전송준비     rmsg = msg     rh = SHA256.new(rmsg).digest()      # 파일에서 전자서명을 로드     rsign = pickle.load(open('my.sign', 'rb'))       # 보낸사람의 공개키 로드     rpublic_key = RSA.importKey(open('public_key.pem', 'rb').read())       # 검증     if rpublic_key.verify(rh, rsign):         print('Verify !!')     else:         print('Denied !!')  if __name__ == '__main__':     main() 

 

 [2] 시연

 

 

 

댓글