Swift

CryptoKit을 사용한 암호화

Phililip
728x90

안녕하세요.

 

애플은 암호화를 위해 CryptoKit이라는 프레임워크를 제공해주고 있어요.

 

그래서 이번에는 CryptoKit 기본 사용법에 대해 알아보려고 합니다.

 

 


 

# 1. 공개키(비대칭키) 암호화

 

일단 공개키 암호화가 뭔지 알아야겠죠???

 

 

## 1.1 공개키 암호화란?

 

공개키 암호화 또는 비대칭키 암호화라고도 불려요.

 

공개키 암호화 방식에 필요한 것이 공개키와 개인키입니다.

 

공개키는 공개되어 있는 키로, 남들도 쉽게 알 수 있는 값이에요.

(공개키를 서로 공유할 때, 탈취를 방지하기 위해서 디피 헬만 알고리즘이라는 것을 사용하기도 합니다.)

 

대신 개인키는 남들한테는 공유하지 않은, 나만 알고 있는 값입니다.

 

그래서 공개키와 개인키로 메시지를 암호화, 복호화를 하는 것이죠.

 

(공개키로 암호화한 것은 개인키로 복호화가 가능하고, 반대로 개인키로 암호화한 것은 공개키로 복호화가 가능합니다.)

 

 

 

공개키 암호화 방식에 대해 예시를 통해 간단히 설명할게요.

 

메시지 송신자(A)가 메시지 수신자(B)한테 메시지를 전송하려고 한다.
A는 B의 공개키로 메시지를 암호화해서 B한테 전송
B는 받은 메시지를 B의 개인키로 메시지 복호화

 

이때, C라는 사용자가 암호화된 메시지를 탈취한다고 했을 때,

 

C는 B의 개인키를 모르기 때문에 메시지 복호화를 할 수가 없어요. (메시지 평문이 뭔지 알 수가 없겠죠???)

 

이렇게 공개키 암호화 방식을 사용하면, 메시지가 탈취당해도 어떤 메시지인지 모르게끔 할 수가 있어요.

 

 

 

 

근데.... 만약 C가 A인 척 B의 공개키로 C가 작성한 메시지를 암호화해서 B한테 보낼 수도 있겠죠???

 

그럼 B는 B의 개인키로 복호화가 가능하니, "A가 보낸 메시지가 잘 도착했군..." 이라고 생각할 수 있어요.

 

 

이때 필요한 것이 서명이라는 개념입니다.

 

 

 

## 1.2 서명

서명이란, 메시지를 보내는 사람(A)이 자신의 개인키(A의 개인키)로 서명해서 메시지 보낸 사람이 본임(A) 임을 입증하는 것이에요.

 

이것도 예시로 간단히 설명해볼게요.

 

메시지 송신자(A)가 메시지 수신자(B)한테 메시지를 전송하려고 한다.
A는 메시지를 A의 개인키로 암호화한 메시지를 만든다. (서명)
A는 메시지를 B의 공개키로 암호화한다.
B한테 암호화한 메시지와 서명문을 같이 전달한다.
B는 B의 개인키로 암호화한 메시지를 복호화한다.(암호화 메시지 -> 메시지)
또, B는 A의 공개키로 서명문을 복호화한다. (서명 -> 메시지')
메시지와 메시지'가 같다면, A가 메시지를 보내었다는 것이 보장된다.

 

 

## 1.3 CrytoKit 사용방법

CryptoKit 프레임워크는 ECC 알고리즘을 독점적으로 제공하고 있으며

 

P256, P348, P521, Curve25519 알고리즘 중에 선택이 가능합니다.

 

let privateKey = Curve25519.Signing.PrivateKey()        // 개인키 생성
let publicKey = privateKey.publicKey                    // 공개키 생성

let signature = try privateKey.signature(for: messageDigest)    // 서명
publicKey.isValidSignature(signature, for: messageDigest)       // 검증

 

 

 

# 2. Hash Function

Hash function으로 암호화를 한다는 것은, 일방향 함수이어야 하고, 동일한 메시지는 항상 동일한 해쉬값을 가지며, 해쉬값으로 유일한 결괏값을 얻어야 한다는 것입니다.

 

CryptoKit 프레임워크는 SHA-256, SHA-384, SHA-512 알고리즘을 제공합니다.

 

let hashedPassword = SHA256.hash(data: Data(password.utf8))     // SHA-256 알고리즘

 

 

 

 

# 3. 대칭키 암호화

 

## 3.1 대칭키 암호화란?

메시지 송신자와 수신자 간에 동일한 키를 가지고 암호화 & 복호화하는 것을 말해요.

 

공개키(비대칭키) 암호화보다 덜 복잡하고 더 빠른 것이 특징입니다.

 

그만큼, 대칭키가 탈취당하지 않도록 더욱 유의해서 사용해야 합니다.

 

만약 서버-클라 간 대칭키를 공유하고자 한다면 아래같이 암호화해서 공유를 해야 할 거예요..

(여러 가지 대칭키 공유 방식 중 가장 간단한 방식을 소개해볼게요.)

 

서버가 대칭키를 생성하고, 클라의 공개키를 사용하여 대칭키를 암호화한 다음에 클라에게 전달한다.
클라는 클라 개인키로 복호화해서 대칭키를 얻는다.

 

 

## 3.2 CryptoKit 사용방법

 

CryptoKit을 사용하여 SymmetricKey(대칭키)를 생성합니다.

 

let keyData = Data(base64Encoded: base64EncodedKeyString)
let symmetricKey = SymmetricKey(data: keyData)

 

 

CryptoKit은 대칭키 알고리즘 중 AES-GCM, ChaCha20-Poly 1305를 지원합니다.

 

let encryptedData = try ChaChaPoly.seal(data, using: symmetricKey).combined     // 암호화
let sealedBox = try ChaChaPoly.SealedBox(combined: encryptedData)
let decryptedData = try ChaChaPoly.open(sealedBox, using: symmetricKey)         // 복호화

 

 

CryptoKit은 대칭키 기반 해쉬 함수인 HMAC을 지원합니다.

 

let authenticationCode = HMAC<SHA512>.authenticationCode(for: data, using: symmetricKey)    // 서명
let isValid = HMAC<SHA512>.isValidAuthenticationCode(Data(authenticationCode),              // 검증
                                                          authenticating: data,
                                                          using: symmetricKey)

 

 

## 참고

 

- https://tanaschita.com/20220105-public-key-cryptography-with-cryptokit/

- https://tanaschita.com/20220105-using-hash-functions-in-swift/

- https://tanaschita.com/20220120-symmetric-key-cryptography-with-cryptokit/

 

 

 


 

 

이번 글은 여기서 마무리.

 

 

 

 

반응형