iOS개발/Swift 기본

Swift Cryptokit 으로 대칭/비대칭 키를 알아보자 (+PKI)

Larooly 2025. 5. 27. 23:01

안녕하세요.

이번 주제는 작성을 할까 말까 고민을 많이 했는데 개념이 낯선 것일뿐

코드 자체는 어려운게 아니기 때문에 최대한 쉽게 개념을 이해해보고 만들어 보도록 하겠습니다. 

 

그래서 오늘의 주제는 대칭/비대칭키 만들고 활용해보기입니다. 

비대칭키의 경우 PKI 처럼 공개키/개인키를 나누어 만들어 볼꺼에요.

 

* PKI 가 무엇인가요? (Public Key Infrastructure)

- 공개키 기반의 구조를 의미합니다. 

- 즉 공개키 / 개인키를 사용해 암호화/복호화 를 하는 구조를 의미합니다.

- PKI 는 그래서 비대칭키 구조 를 기반으로 합니다. (암/복호화시 사용된 키가 다른 경우)

 

*  대칭키? 비대칭키 이건 뭔가요? 

- 간단하게 그려보면 아래와 같습니다. 

대칭키 구조

- 대칭키 구조 : 암/복호화시 같은 키를 사용한 경우 

비대칭키 구조

- 비대칭키 구조 : 암/복호화시 다른 키를 사용하는 경우 

 

PKI 의 개념은 비대칭 구조를 기반으로 만들어졌다고 생각하시면 될 것 같습니다.

 

그래서 이걸 Apple에서 기본으로 제공해주시는 CryptoKit 으로 만들어보는게 오늘의 목적입니다. 

(생각보다 간단하죠?)

 

그래서 코드를 시작하기전에 아래 한줄 먼저 추가하겠습니다.

import CryptoKit //ios 13.0이상만 가능

 

일단 대칭키부터 해볼까요? 

대칭키는 생성부터 암복호화까지 CrptoKit 에서 지원하기때문에 암복호화까지 해보겠습니다. 

 

* 대칭키 생성 및 암복호화 

- 여기서 AES 는 대칭키 알고리즘 중 하나입니다.

print("Hello, Swift!")
// 암호화할 내용
let plainData = "Hello, Swift!".data(using: .utf8)
// 키 생성
let sysKey = SymmetricKey(size: .bits256)
// 키를 이용한 암호화
if let cryptBox = try? AES.GCM.seal(plainData!, using: sysKey){
    // 암호화 성공시 데이터 출력(sealBox 라서 combine을 해야 Data 타입으로 바뀜)
    print("Crypt Data : \(cryptBox.combined!.base64EncodedString())")
    // 복호화 -> 암호화시 사용한 키를 넣어주세요.
    if let decryptData = try? AES.GCM.open(cryptBox, using: sysKey){
    	// 복호화한 내용 출력
        print(String(data: decryptData, encoding: .utf8)!)
    }
}

 

* 실제 결과물 

Hello, Swift!
Crypt Data : bLNmfBvO+Kw3sl59e29ZeGY1JeSIoa005sQhTlP3lilUurNnW9MLGBc=
Hello, Swift!

 

간단하죠? 명령어가 어색한 것 뿐이지 굉장히 간단합니다. 

이제 비대칭 구조를 만들어볼께요.

 

* 비대칭 키 생성

// CryptoKit 은 ECC 를 기반으로 생성
// 암복호화용
let privateKey = P256.KeyAgreement.PrivateKey()
let publicKey = privateKey.publicKey
// 서명용
let privateSignKey = P256.Signing.PrivateKey()
let publicSignKey = privateSignKey.publicKey

- 자세히 보시면 키가 2가지 방법인데 이는 사용법에 따라 달라집니다. 

실제로 이렇게 뜹니다

- 암호화를 목적으로 하느냐 서명을 목적으로 하느냐로 나뉘게 됩니다. 

- 공식 설명을 번역해서 보면 아래처럼 나옵니다. 

  • KeyAgreement : NIST P-256 타원 곡선 디피 헬만(ECDH) 키 교환을 수행하여 두 사용자 간의 공유 비밀을 생성하는 데 사용되는 메커니즘입니다.
  • Signing : NIST P-256 타원 곡선 디지털 서명 알고리즘(ECDSA)을 사용하여 암호화 서명을 생성하거나 검증하는 데 사용되는 메커니즘입니다.

사용 목적이 다르기 때문에 원하시는걸로 선택하시면 될 것 같습니다. 

 

아쉽게도 CryptoKit으로는 아직 암복호화 구현은 지원하지 않는다고 합니다. 

(보통은 다른 오픈 소스 라이브러리를 사용한다고 합니다.)

 

그래서 저희는 CryptoKit이 지원하는 기능 중 서명을 생성 및 검증을 이용해보겠습니다.

서명이니 Signing 을 이용해서 만든 걸 활용해봅시다.

 

* 비대칭키 서명 생성 및 검증 

// 서명용 키 생성
let privateSignKey = P256.Signing.PrivateKey()
let publicSignKey = privateSignKey.publicKey
// 메시지 준비
let plainData = "Hello Swift".data(using: .utf8)!
// 서명 생성
let makeSign = try! privateSignKey.signature(for: plainData)
print("서명 생성 결과: \(makeSign.derRepresentation.base64EncodedString())")
// 공개키로 서명 검증
let isValid = publicSignKey.isValidSignature(makeSign, for: plainData)
print("서명 검증 결과: \(isValid)")

 

* 실제 결과물

서명 생성 결과: MEUCIQDjwdgMfIxX0GSu1H8svGlo4Mgix63RbWBlyw/XLGLQowIgbTBNRopVTE9uipFh6qyLV15fyDVNXbX58lrg8xkcsV0=
서명 검증 결과: true

 

 

암복호화 쪽이 제공이 아직 안되는건 아쉽지만 

서명이 가능하다는 것은 처음 알았습니다.

 

이번엔 우연히 접한 개념들을 CryptoKit 으로 만들어 봤습니다. 

(간단하게 정리하려했는데 복잡해보이네요...)

저처럼 암복호화 부분을 잘 모르시거나 해메시는 분들에게

도움이 되었으면 좋겠습니다. 

 

오늘도 파이팅입니다.