AES GCM 암호화

개발者·2022년 3월 11일
2

CS

목록 보기
4/7

originebcother
원본 이미지EBCEBC 이외

암호화(Encryption) vs 해쉬(Hash)

암호화

  • 암호화 알고리즘에는 AES, RSA 등 존재

  • 암호화는 양방향 통신을 전제로 하므로 암호화복호화가 가능

해시

  • 해시 알고리즘에는 MD5, SHA 등 존재

  • 고정된 문자열을 변환

  • 복호화를 위해 사용하지 않음

  • 암호화 보다 연산이 빠름


해시

MD5 (Message Digest)

  • 128비트 암호화 해시함수

  • 원본 그대로인지를 확인하는 무결성 검사 등에 사용

  • 해킹에 취약하므로 SHA 를 권장

  • 임의의 길이를 입력받아 128비트 고정길이 값을 출력

MD5("Apple is red")

3ac529210b9b73c3b5497a5b44d9f5f0

SHA (Secure Hash Algorithm)

  • 서로 관련된 암호학적 해시 함수들의 모음
  • SHA-0, SHA-1, SHA-2(224, 256, 384, 512) 존재
  • SHA-0, SHA-1에 대한 공격 발견
  • SHA-256은 256비트로 구성되며 64자리 문자열을 반환
SHA1("Apple is red")

6623D1863D6CAF11D12D8D203A99D5D4A853BFF4
SHA-256("Apple is red")

45071BFB469B99FD777D31B007A18572F2D9243F9B0B572B4C2754DB4EC1181E

암호화

RSA (Ron Rivest, Adi Shamir, Leonard Adleman)

  • 공개키 암호시스템의 하나로, 암호화뿐만 아니라 전자서명이 가능한 최초의 알고리즘

  • 공개키(Public key), 개인키(Private key)가 존재

  • 대칭키 알고리즘에 비해 느림

AES (Advenced Encryption Standard)

  • 암호화와 복호화 과정에서 동일한 키를 사용하는 대칭키 알고리즘

  • 2001년 미국 표준 기술 연구소(NIST)에 의해 제정된 암호화 방식

  • AES 표준은 여러 Rijindael 알고리즘 중 블록 크기가 128비트인 알고리즘

Block Cipher Mode(블록 암호 운영 모드)

  • ECB (Electronic Code Block)

  • 가장 기본적인 타입

  • 항상 같은 결과가 나오기 때문에 역추적 가능

  • 암호화 키 유추 가능

  • CBC (Ciper Block Chaining)

  • ECB의 단점을 보완

  • 암호화 키에 IV(Initial Vector)를 추가해서 항상 같은 결과가 나오는 문제를 해결

  • 병렬처리 불가

  • GCM (Galois/counter mode)

  • CBC 의 취약점을 보완

  • 데이터 값의 Hash 가 암호문에 포함 -> 데이터 복호화 시 변조 확인 가능

  • 병렬처리 가능


GCM 성능 테스트

8.71MB 이미지 암호화 50ms 내외, 복호화 80ms 내외
99.0MB 이미지 암호화 600ms 내외, 복호화 800ms 내외


How to use

AES GCM Encryption

  • plaintext 암호화할 대상 데이터
  • key 대칭키
  • nonce (number once)

nonce를 암호화된 데이터에 추가해서 전달.

func Encryter(plaintext []byte) string {
	block, err := aes.NewCipher(key)
	if err != nil {
		log.Fatal(err)
	}
	
	nonce := make([]byte, 12)
	_, err := io.ReadFull(rand.Reader, nonce)
	if err != nil {
		log.Fatal(err)
	}
	
	aesgcm, err := cipher.NewGCM(block)
	if err := nil {
		log.Fatal(err)
	}
	

	// func (cipher.AEAD).Seal(dst []byte, nonce []byte, plaintext []byte, additionalData []byte) []byte
	// dst에 nonce를 인자로 줘서 리턴에 nonce를 추가. 
	ciphertext := aesgcm.Seal(nonce, nonce, plaintext, nil)
  
	ret := fmt.Sprintf("%x", ciphertext)

	return ret
}

AES GCM Decryption

func GCMDecrypter(cipherText string) []byte {
	ciphertext, _ := hex.DecodeString(cipherText)
	
	block, err := aes.NewCipher(key)
	if err != nil {
		log.Fatal(err)
	}
	
	aesgcm, err := cipher.NewGCM(block)
	if err != nil {
		log.Fatal(err)
	}
	
	nonceSize := aesgcm.NonceSize() // default 12byte
	nonce, pureCiphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]

	plaintext, err := aesgcm.Open(nil, nonce, pureCiphertext, nil)
	if err != nil {
		log.Fatal(err)
	}

	return plaintext
}

Reference

profile
solrasido

0개의 댓글