본문 바로가기
3학년 학사/네트워크 보안

b[네트워크 보안] # 11. 이메일, S/MIME

by whiteTommy 2024. 12. 6.
반응형
더보기

목차

  • 이메일 구조 및 형식
  • 이메일의 위협과 이메일 보안
  • S/MIME

 

예상 문제

  • MIME 가 나오게 된 배경
  • 이메일 보안 위협 4가지와 설명
  • S/MIME 기능 4가지
  • EnvelopedData 생성과정
  • SignedData 생성 과정

 

이메일 구조

RFC 5598 (Internet Mail Architecture) - 개념 구조

  • 이메일 작성 및 전송
    • 발신자 
      • Message User Agent (MUA):
        • 이메일을 작성하고 전송하는 클라이언트 소프트웨어이다.
        • 작성된 이메일은 MSA로 전달된다.
    • Mail Submission Agent (MSA)
      • 사용자가 작성한 이메일을 ESMTP(Extended SMTP)를 통해 서버로 제출한다.
      • 주로 발신자의 ISP 또는 메일 제공 업체가 제공하는 SMTP 서버 역할을 한다.
      • 이메일 작성 후 "보내기"를 누르면 이 단계가 시작된다.
  • 이메일 전송
    • Message Transfer Agent (MTA)
      • 이메일 서버 간 메시지를 전달하는 역할을 한다.
      • SMTP 프로토콜을 사용하여 발신자와 수신자의 서버 사이에서 다수의 MTA를 거쳐 메시지를 전달한다
      • 발신자 서버 → 중계 서버 → 수신자 서버로 이메일이 이동한다
  • 이메일 저장 및 수신
    • Mail Delivery Agent (MDA)
      • 최종 수신자의 메일박스에 이메일을 전달한다.
      • MTA로부터 전달된 이메일을 수신자의 Message Store (MS)에 저장한다.
    • Message store (MS)
      • 수신자의 이메일 데이터를 저장하는 공간이다
      • 수신자는 여기에서 POP3 또는 IMAP을 통해 이메일을 확인한다
    • Message User Agent (MUA)
      • 수신자는 이메일 클라이언트를 통해 이메일을 확인한다.
        • IMAP: 서버에 이메일을 유지하며 동기화 지원.
        • POP3: 이메일을 로컬로 다운로드.
  • 이메일 프로토콜
    • SMTP (Simple Mail Transfer Protocol)
      • 발신지에서 목적지까지 인터넷을 통해 메시지를 이동하는데 사용하는 프로토콜
      • 이메일을 서버로 제출(MSA)하거나 서버 간(MTA) 전송할 때 사용.
    • ESMTP (Extended SMTP): SMTP의 확장 버전으로, 이메일 제출과 인증 절차를 처리.
    • IMAP (Internet Message Access Protocol)
      • 메일 서버에서 메시지를 수신하는 데 사용 
    • POP3 (Post Office Protocol 3)
      • 메일 서버에서 메시지를 수신하는 데 사용 

 

SMTP 클라이언트-서버 프로토콜

  • 정의
    • 클라이언트와 서버 간 이메일 전송 과정을 정의하는 프로토콜
    • 클라이언트가 서버에 TCP 접속을 하면 시작됨
  • 작동 방식

  • C → S 명령 (클라이언트 → 서버):
    • 구성
      • 1줄 텍스트
      • 4글자 명령 + argument 
    • 주요 명령:
      • HELO: 클라이언트가 서버와 연결 시작. (예: HELO bar.com)
      • MAIL FROM: 이메일 발신자를 정의. (예 : MAIL FROM:<Smith@bar.com>)
      • RCPT TO: 수신자 주소를 정의. (예 : RCPT TO:<Jones@bar.com>)
      • DATA: 이메일 본문을 전송. 
  • S → C Reply (서버 → 클라이언트):
    • 구성
      • 1줄 이상 텍스트
      • 3자리수 코드 + 추가 정보
        • 2xx: 성공 (예: 250 - 요청 완료).
        • 4xx: 클라이언트 오류
        • 5xx: 서버 오류

 

POP3 (Post Office Protocol 3)

  • 특징
    • TCP 포트 110번을 사용. 
    • 사용자는 이름과 비밀번호로 인증.
    • 기본적으로 이메일을 다운로드 후 서버에서 삭제.
    • 허가가 나면 UA 는 메일을 검색하거나 삭제하기 위해 POP3 명령어 사용
  • 주요 명령
    • USER: 사용자 계정을 지정.
    • PASS: 비밀번호를 입력해 인증.
    • QUIT: 연결 종료.
    • STAT : 모든 메시지의 전체 크기와 개수
    • LIST: 메일 목록을 조회. (크기와 인덱스)
    • RETR message# : 해당 이메일을 읽음
    • DELE message#: 해당 이메일 삭제.
    • NOOP : No-op, 연결이 오픈된채로 유지
    • RSET : mailbox 리셋.

 

IMAP 

  • 특징
    • POP3보다 더 많은 기능을 제공, 인증 강화
      • 메시지를 읽음으로 표시
      • 전자 메일이 오면 이를 장치로 푸시
    • TCP 포트 143번 사용.

 

 

이메일 포맷

  • 구성 요소
    • 봉투 (Envelope):
      • 전송하는 배달을 완수하는 데 필요한 모든 정보 입력 
      • 이메일 전송에 필요한 메타데이터(발신자, 수신자, 경로 등)를 포함.
      • 이메일 헤더와는 구분된다
    • 컨텐츠 (Content)
      • 수신자에게 전달하려고 하는 객체로 구성.
        • 메시지는 헤더(header)와 바디(body)로 나뉘며, 이 두 부분은 하나의 빈 줄로 구분된다.
        • 메일 시스템의 UA 부분에서 처리한다.
          • 헤더 (Header): 발신자, 수신자, 제목 등 메타 데이터를 포함.
          • 바디 (Body) : 메시지의 실제 내용.
          • 예시
            • Date: October 8, 2009 2:15:49 PM EDT  
              From: “William Stallings” <ws@shore.net>  
              Subject: The Syntax in RFC 5322
              To: Smith@Other-host.com  
              Cc: Jones@Yet-Another-Host.com  

              Hello. This Section begins the actual message only, ...

 

MIME (Multipurpose Internet Mail Extension)

  • SMTP/5322의 한계
    • 실행 파일이나 바이너리 객체를 전송하지 못함
      • 바이너리 => 텍스트 변환을 위해 UUencode/UUdecode 같은 변환을 사용
    • 과거에는 텍스트 게시판에 이미지 파일을 encoded txt 로 업로드
    • 다국어 텍스트를 전송하지 못함 (SMTP는 7-bit ASCII 코드 사용)
    • 특정 크기 이상의 메일 메시지를 거절
  • MIME 확장
    • 다국어나 바이너리 전송을 위한 포맷
  • 요소
    • RFC 5322 이메일에 포함되는 5개의 MIME 필드:
      1. MIME-버전 (MIME-Version): MIME 프로토콜의 버전, 보통 1.0으로 설정.
      2. 콘텐츠-유형 (Content-Type): 메시지 또는 파일의 데이터 형식.
      3. 콘텐츠-전송-인코딩 (Content-Transfer-Encoding): 메시지 콘텐츠를 인코딩하는 방법.
      4. 콘텐츠-아이디 (Content-ID): 콘텐츠를 식별하는 고유 ID.
      5. 콘텐츠-표현 (Content-Description): 콘텐츠에 대한 설명 제공.
    • 필드 포맷
      • 키워드 : 값 ; 파라메터 = 값
        ex) Content-Type: multipart/mixed; boundary="simple boundary"

 

 

 

MIME 콘텐츠 유형

유형 서브유형 설명
텍스트 Plain
Enriched
형식화되지 않은 텍스트; ASCII 또는 ISO 8859
다양한 형식 유형 제공
멀티파트(Multipart) Mixed 파트는 서로 독립적이지만 같이 전송된다. 파트는 메일 메시지에 나타나는 순서대로 수신자에게 나타나야만 한다.
Parallel 수신자에게 파트를 전달하는 순서가 정의되지 않는다는 것이 Mixed 와 다르다
Alternative 다른 파트는 동일한 정보의 다른 버전이다. 원래 정보에 충실한 정보에 따라 순서가 정해지고 수신자의 메일 시스템은 사용자의 가장 좋은 ("best") 버전을 나타내야만 한다.
Digest Mixed 와 비슷하다. 그러나 각 파트의 기본 type/subtype 은 message/rfc822 이다.
메시지(Message) rfc822 body 는 RFC 822 에 준하는 캡슐화 된 메시지이다.
Partial 수신자에게 투명한 방법으로 큰 메일을 단편화 할 수 있게 한다.
External-body 다른 곳에 있는 객체 포인터를 포함하고 있다.
정지 화상(Image) jpeg 정지 화상은 JPEG 형식이다. JFIF 인코딩이다.
gif 정지 화상은 GIF 형식이다.
비디오(Video) mpeg MPEG 형식이다.
오디오(Audio) Basic 표본 추출 비율이 8kHz인 단일-채널 8-bit ISDN μ-law 인코딩이다.
응용(Application) PostScript Adobe Postscript
Octet-stream 8-bit 바이트로 된 일반적인 2진 데이터이다.

 

MIME 필드

  • 콘텐츠-전송-인코딩(Content-Transfer-Encoding):
    • 메시지 본문을 나타내는 데 사용 
    • 메일 전송에 적합한 형태의 전환 유형

      7 bit 데이터는 모두 ASCII 문자의 짧은 줄로 표현된다
      8 bit 줄은 짧지만, 그 안에 non-ASCII 문자 (high-order 비트를 갖는 octet 들) 가 있을 수 있다.
      binary non-ASCII 문자를 표현할 수 있을 뿐만 아니라 SMTP 전송을 위해 줄이 짧을 필요가 없다
      quoted-printable (인용-인쇄) 만일 인코딩할 데이터가 대부분 ASCII 텍스트이면, 인코딩된 데이터 형식을 사람이 대부분 읽을 수 있는 상태로 남아 있도록 데이터를 인코딩한다.
      base64 6-bit 블록을 입력해서 8-bit 블록으로 출력하는 인코딩이다. 이 출력은 모두 인쇄할 수 있는 ASCII 문자이다.
      x-token 표준화된 인코딩이 아닌 경우를 표시한다.
  • 콘텐츠-아이디(Content-ID): 다중 콘텍스트 안에서 MIME 개체를 유일하게 식별.
  • 콘텐츠-설명(Content-Description):
    • 본문에 포함된 객체의 텍스트 표현
      • 객체가 읽을 수 없는 형태인 오디오 데이터 같은 경우에 유용

 

MIME Type Handler

  • 모든 content-type에 대한 처리를 할 수 없음
    • content-type 별 응용 프로그램 설정
      • MIME 타입에 따라 특정 응용 프로그램이 처리하도록 설정할 수 있다. 
        • 브라우저에서 특정 파일 형식(예: PDF, 이미지)에 대해 응용 프로그램(뷰어)을 호출.
    • 레지스트리 편집기를 사용한 설정
      • 윈도우 운영체제에서는 레지스트리를 편집하여 특정 MIME 타입을 처리하는 응용 프로그램을 연결할 수 있다
      • 관련 경로: 컴퓨터\HKEY_LOCAL_MACHINE\SOFTWARE\Classes

 

이메일 위협과 종합적 이메일 보안

이메일 보안 위협

  • 인증-관련 위협(Authentication-related threats): 기업 이메일 시스템에 허가받지 않은 접근 허용
  • 무결성-관련 위협(Integrity-related threats): 이메일 콘텐츠가 허가 없이 변경될 수 있는 위험.
  • 기밀성-관련 위협(Confidentiality-related threats): 민감한 정보가 노출될 수 있는 위험.
  • 가용성-관련 위협(Availability-related threats): 종단 사용자가 메일 전송이나 수신하는 것을 방해

 

이메일 보안 위협과 완화

위협 송신자라고 주장하는 영향 수신자 영향 완화
기업에서 불법적 MTA 가 보낸 이메일 (예, 악성 소프트웨어 봇넷(botnet)) 평판 실추, 기업의 합법적 이메일을 스팸/피싱 공격으로 간주하여 차단됨 악성 링크가 포함된 UBE 와 이메일을 사용자 수신박스로 배달할 수 있다 도메인 기반 인증 기술 설치. 이메일에 디지털 서명을 적용.
스푸핑 되었거나 등록되지 않은 송신 도메인을 이용해 보낸 메시지 평판 실추, 기업의 합법적 이메일을 스팸/피싱 공격으로 간주하여 차단됨 악성 링크가 포함된 UBE 와 이메일을 사용자 수신박스로 배달할 수 있다 도메인 기반 인증 기술 설치. 이메일에 디지털 서명을 적용.
위장된 송신 주소나 이메일 주소(예, 피싱, 공격(spear) 피싱)에서 보낸 이메일 평판 실추, 기업의 합법적 이메일을 스팸/피싱 공격으로 간주하여 차단됨 악성 링크가 포함된 UBE 와 이메일을 배달 할 수 있다.
사용자는 의도하지 않게 민감한 정보나 PII 를 누설한다.
도메인 기반 인증 기술 설치. 이메일에 디지털 서명을 적용.
전송중 변조된 이메일 민감한 정보나 PII 유출 민감한 정보 유출, 변경된 메시지에 악성 정보 포함 가능성 서버 간의 이메일 전송을 TLS 로 암호화, end-to-end 이메일 암호화
이메일 트래픽 모니터링이나 갈취를 통한 민감한 정보(예, PII) 유출 민감한 정보나 PII 유출 민감한 정보 유출, 변경된 메시지에 악성 정보 포함 가능성 서버 간의 이메일 전송을 TLS 로 암호화, end-to-end 이메일 암호화
원하지 않은 벌크 이메일 (UBE)(즉, 스팸) 송신자라고 주장하는 송신자가 스푸핑되지 않는 한 영향 없음 악성 링크가 포함된 UBE 와 이메일을 배달 할 수 있다. UBE 를 처리할 수 있는 기술
기업의 이메일 서버에 대한 DoS/DDoS 공격 이메일 전송 불가 이메일 수신 불가 다중 메일 서버나 클라우드-기반 이메일 제공자 사용

 

 

S / MIME (Secure / Multipurpose Internet Mail Extension)

  • 정의 : 인터넷 이메일 표준 MIME(Multipurpose Internet Mail Extensions)에 보안 기능을 추가한 기술
    • RSA PKCS#7 을 MIME 인터넷 이메일 형식에 추가
  • 특징
    기능 일반적 알고리즘 기본 동작
    디지털 서명 RSA / SHA-256 SHA-256 으로 메시지 해시 코드를 생성한다. 이 메시지 다이제스트를 송신자의 개인 키를 가지고 RSA 로 암호화하고 메시지에 포함한다.
    메시지 암호화 AES-128 with CBC 송신자가 생성한 일회용 세션 키를 이용해 CBC 모드의 AES-128 로 메시지를 암호화한다. 세션 키를 수신자의 공개 키를 이용하여 RSA 로 암호화하고 메시지에 포함시킨다.
    압축 제한 없음 메시지를 압축하여 저장하거나 전송한다
    이메일 호환성 Radix-64 변환 이메일 응용이 투명하도록 암호화된 메시지를 기저64 (radix 64) 로 변환하여 ASCII 스트링으로 만든다

 

S/MIME 콘텐츠 Type

  • Data:
    • 내부 MIME-인코딩된 메시지 콘텐츠.
      • 보안 처리를 하기 전의 원본 데이터 구조를 의미하며, S/MIME 적용 후에 외부 메시지로 변환
    • SignedData, EnvelopedData, CompressedData 콘텐츠 유형 속에 캡슐화.
  • SignedData: 디지털 서명이 포함된 데이터.
  • EnvelopedData: 암호화된 콘텐츠 + 암호화 키
  • CompressedData: 압축된 메시지
  • 인코딩
    • 위의 4가지 모두 BER (Basic Encoding Rules) 포맷 : octet string
    • 외부 MIME 메시지 안에서 Base64 로 전송 부호화
  • 예시
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hello, this is the email body.
Attachment: report.pdf

 

Content-Type: application/pkcs7-mime;
 smime-type=enveloped-data;
 name="smime.p7m"
Content-Transfer-Encoding: base64

MIIC9AYJKoZIhvcNAQcDoIIC5TCCAuECAQAxggEsMIIBKAIBADBcMFoxCzAJBgNVBAYTAlVTMQsw...

 

 

EnvelopedData 생성 과정

  1. Pseudo Random 세션 키 생성: 데이터 암호화를 위한 세션 키를 생성.
  2. 데이터 암호화 : 세션키를 가지고 AES-128 CBC 모드로 메시지를 암호화
  3. 수신자 RSA 공개 키로 세션 키 RSA 암호화: 수신자의 RSA 공개 키를 사용해 보안성을 높임.
  4. 각 수신자를 위해 RecipientInfo 블록 준비
    • 버전 (Version)
    • 수신자의 공개 키 인증서 식별자 (Recipient ID (Issuer and s.no.))
    • 세션 키 암호에 사용된 알고리즘 식별자 (Key Encryption Algorithm) : RSA 
    • 암호화된 세션 키 포함 (Encrypted key)
  5. 세션 키로 메시지 내용을 암호화

  • 예시
    Content-Type: application/pkcs7-mime;smime-type=enveloped-data; name="smime.p7m"
    Content-Transfer-Encoding: base64
    Content-Disposition : attachment; filename = smime.p7m
    
    rfvbnj756tbBghyHhHUujhJhjH77n8HHGT9HG4VQpfyF467GhI
    GfHfYT67n8HHGghyHhHUujhJh4VQpfyF467GhIGfHfYGTrfvbnj
    T6jH7756tbB9Hf8HHGTrfvhJhjH776tbB9HG4VQbnj7567GhIGf
    HfYT6ghyHhHUujpfyF40GhIGfHfQbnj756YT64V

 

SignedData 생성 과정

  1. 메시지 다이제스트 알고리즘 선택 (SHA 혹은 MD5)
  2. 서명될 내용의 메시지 다이제스트나 해시 함수 값을 계산
    • 설명: 메시지(본문 및 첨부 파일 등)의 내용을 입력으로 받아 선택된 해시 알고리즘을 통해 다이제스트 값을 계산
    • 결과:
      • 메시지 내용을 고정된 크기의 고유 해시 값으로 변환.
      • 이 해시 값은 메시지가 변경되지 않았음을 확인하는 기준점 역할을 한다.
  3. 서명자의 개인 키로 메시지 다이제스트 암호화
    • 설명: 계산된 해시 값을 서명자의 개인 키를 사용하여 암호화한다.
    • 목적: 암호화된 해시 값은 디지털 서명으로 사용되며, 이를 통해 서명자가 메시지를 작성했음을 인증할 수 있다
    • 결과: 수신자는 서명자의 공개 키를 사용해 디지털 서명을 복호화하고, 메시지의 다이제스트를 확인하여 무결성을 검증할 수 있다.
  4. SignerInfo 블록 생성
    • 구성 요소:
      • 서명자의 공개 키 인증서.
      • 메시지 다이제스트 알고리즘 식별자.
      • 메시지 다이제스트를 암호화하는 데 사용된 알고리즘 식별자
      • 암호화된 메시지 다이제스트

 

실습 : S / MIME 메일 보내기

  • 구성

 

  • 순서
    • Enveloppeddata 사용
      1. 수신자 인증서 필요 -> 생성
        • $ openssl req -x509 -newkey rsa : 2048 -nodes -days 365 -out recipient.pem
          • 이메일 주소를 자신의 것으로
            => privkey.pem, recipient.pem 생성
      2. S/MIME 객체 생성
        • M2Crypto 설치
          • $ sudo pip3 install M2Crypto
        • S/MIME 객체 생성 test : encrypt.py
          • S/MIME메시지를 보여줌
            # encrypt.py
            from M2Crypto import BIO, Rand, SMIME, X509
            
            def makebuf(text):
            	return BIO.MemoryBuffer(text)
            
            def encrypt(text, email):
            	# Make a MemoryBuffer of the message.
            	buf = makebuf(text.encode())
            
            	# Seed the PRNG.
            	Rand.load_file('randpool.dat', -1)
            
            	# Instantiate an SMIME object.
            	s = SMIME.SMIME()
            
            	# Load target cert to encrypt to.
            	x509 = X509.load_cert('recipient.pem')
            	sk = X509.X509_Stack()
            	sk.push(x509)
            	s.set_x509_stack(sk)
            
            	# Set cipher: AES_128 in CBC mode.
            	s.set_cipher(SMIME.Cipher('aes_128_cbc'))
            
            	# Encrypt the buffer.
            	p7 = s.encrypt(buf)
            
            
            	# Output p7 in mail-friendly format.
            	out = BIO.MemoryBuffer()
            
            	out.write('From: %s\n' %email)
            	out.write('To: %s\n' %email)
            	out.write('Subject: M2Crypto S/MIME testing\n')
            	s.write(out, p7)
            
            	# Save the PRNG's state.
            	Rand.save_file('randpool.dat')
            	return out.read()
            
            if __name__ == '__main__':
            	print(encrypt("test", "abc@def.com").decode() )

      3. e-mail 로 보내기
        1. Gmail API 시작
          1. Gmail API 등록
            https://console.cloud.google.com
      4. 메일 수신하여 확인하기

 

 

OAUTH

  • 정의 : 인증 프로토콜로, 사용자 비밀번호를 직접 공유하지 않고 제3자 애플리케이션이 사용자 리소스에 안전하게 접근할 수 있도록 하는 방식
  • 특징
    • 사이트 간 Single Sign-On (SSO): 하나의 계정으로 여러 웹사이트나 애플리케이션에 로그인.
    • Open API 정보 조회: 개발자가 Google, Twitter, Facebook 등의 API를 통해 사용자의 데이터를 접근할 때 사용

  • 인증 흐름 단계
    1. 트위터 로그인 요청
      • 설명:
        • 사용자가 애플리케이션(Consumer)을 통해 트위터에 로그인을 요청.
        • Consumer는 사용자를 대신해 트위터 API와 통신하려는 애플리케이션.
    2. 트위터 로그인 화면으로 리디렉션
      • 설명:
        • 애플리케이션은 사용자를 트위터의 로그인 페이지로 리디렉션.
        • 사용자는 트위터 계정으로 로그인하고, 애플리케이션에 데이터를 제공할 권한을 승인.
      • 중요 사항:
        • 사용자가 비밀번호를 애플리케이션에 입력하는 것이 아니라, 트위터 공식 로그인 페이지에서 입력.
        • 이는 사용자의 비밀번호를 안전하게 보호.
    3. 사용자 로그인 및 승인
      • 사용자가 트위터 로그인 화면에서 계정 정보를 입력하여 인증을 완료합니다.
      • 사용자는 애플리케이션이 자신의 데이터에 접근할 수 있는 권한을 부여합니다.
    4. 인증 토큰 전달
      • 설명:
        • 트위터는 사용자가 승인한 범위를 나타내는 Access Token(액세스 토큰)을 발급.
        • 이 토큰은 애플리케이션이 트위터 API에 접근할 때 사용됨.
        • Consumer는 이 Access Token을 저장하고, 이후 API 호출 시 사용.
      • 보안: Access Token은 사용자 비밀번호를 대체하여 애플리케이션이 안전하게 데이터를 접근할 수 있게 함
    5. 인증 토큰으로 사용자 정보 조회 또는 이용
      • 설명: 애플리케이션은 받은 Access Token을 사용해 트위터 API를 호출하고, 사용자 데이터를 조회하거나 작업(예: 트윗 작성)을 수행

 

 

구글 API OAUTH

 

  • 단계별 흐름
    1. APP 등록
      • 설명:
        • Google Cloud Platform에서 애플리케이션을 등록.
        • 이 등록은 Google에게 애플리케이션이 신뢰할 수 있는 클라이언트임을 알리는 과정.
    2. 개발자 ID 및 Secret 받기
      • 설명: 애플리케이션이 Google API 서버와 통신하기 위해 필요한 클라이언트 ID와 Secret을 발급받는다.
    3. credentials.json 생성
      • 설명:
        • 클라이언트 ID와 Secret을 포함한 인증 정보를 JSON 파일에 저장.
        • 이 파일은 애플리케이션 코드(send.py)에서 사용된다.
      • 방법
        • OAuth client ID 생성 후 json 파일 다운로드
          • mv 해당 파일 credentials.json
    4. 사용자 추가 : 송신자 이메일 (자기 이메일)

 

토큰 발행 구조

  • 단계별 흐름
    • APP 사용자 등록
      • 설명:
        • 개발자가 애플리케이션 사용자 등록을 설정.
        • Google Cloud Console에서 API를 사용할 수 있도록 이메일을 보낼 애플리케이션 사용자(email)를 등록.
    • 토큰 발행 시작
      • 방법
        • $ pip3 install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib 
        • $ python3 install.py
      • 설명:
        • OAuth 인증 흐름을 시작하기 위해 install.py 를 실행.
        • install.py는 credentials.json 파일을 읽어 인증 요청을 초기화한다.
        • 이 파일에는 Google API 서버와 통신하기 위한 클라이언트 ID클라이언트 Secret 정보가 포함됨
          # install.py
          from __future__ import print_function
          import pickle
          import os.path
          from googleapiclient.discovery import build
          from google_auth_oauthlib.flow import InstalledAppFlow
          from google.auth.transport.requests import Request
          
          
          # If modifying these scopes, delete the file token.pickle.
          SCOPES = ['https://www.googleapis.com/auth/gmail.modify']
          
          
          def main():
              """Shows basic usage of the Gmail API.
              Lists the user's Gmail labels.
              """
              creds = None
              # The file token.pickle stores the user's access and refresh tokens, and is
              # created automatically when the authorization flow completes for the first
              # time.
              if os.path.exists('token.pickle'):
                  with open('token.pickle', 'rb') as token:
                      creds = pickle.load(token)
              # If there are no (valid) credentials available, let the user log in.
              if not creds or not creds.valid:
                  if creds and creds.expired and creds.refresh_token:
                      creds.refresh(Request())
                  else:
                      flow = InstalledAppFlow.from_client_secrets_file(
                          'credentials.json', SCOPES)
                      creds = flow.run_local_server(port=0)
                  # Save the credentials for the next run
                  with open('token.pickle', 'wb') as token:
                      pickle.dump(creds, token)
          
              service = build('gmail', 'v1', credentials=creds)
              service.users().labels().list(userId='me').execute()
          
          if __name__ == '__main__':
              main()
      • 사용자 인증 및 확인
        • 설명:
          • 사용자가 브라우저를 통해 Google OAuth 인증 페이지로 리디렉션.
          • 사용자는 자신의 Google 계정으로 로그인한 후, 애플리케이션이 요청한 API 접근 권한을 승인
          • 승인된 후, Google은 인증 코드를 발급. 
      • 토큰 발행
        • 설명:
          • 애플리케이션은 Google API 서버에 인증 코드를 전달하고, Access Token 및 Refresh Token을 요청합니다.
          • Google은 토큰을 발행하여 애플리케이션에 반환. (token.pickle)
    • 메일 보내기 : 아래의 send.py 코드에서 raw 에서 자기 이메일 입력 후 보내기
      • $python3 send.py
from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from M2Crypto import BIO
from email.mime.text import MIMEText
import base64
import encrypt


# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/gmail.modify']


def main():
    """Shows basic usage of the Gmail API.
    Lists the user's Gmail labels.
    """
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('gmail', 'v1', credentials=creds)

    raw=encrypt.encrypt("0000000hello", "abc@def.com")
    raw= base64.urlsafe_b64encode(raw)
    raw= raw.decode()
    print (raw)
    body={'raw':raw}
    message = service.users().messages().send(userId="me", body=body).execute()
    print (message['id'])


if __name__ == '__main__':
    main()

 

 

메일 내용 복호화 및 확인하기

  • send.py 수정
    • raw = base64.urlsafe_b64encode(raw) 주석 처리
    • print (raw) 밑의 코드들 모두 주석 처리
  • send.py 실행 후 txt 파일로 저장
    • $ python3 send.py > 1.txt
  • 해당 txt 파일을 수신자의 인증서 및 개인키로 decrypt
    • $ openssl smime -decrypt -in 1.txt -recip recipient.pem -inkey privkey.pem
반응형