Secure Coding)대칭, 비대칭 키 암호

시큐어 코딩

Featured image

@

대칭키 암호 방식

대칭 키 암호 방식의 핵심은 “같은 키를 가지고 암호화, 복호화를 진행한다” 이다. 즉, 내가 철수에게 암호화된 파일을 건내 받았는데 철수가 열쇠를 주지 않는다면 나는 영영 못열게 되는 암호방식이다. 대표적으로 DES, SEED, AES가 있다.

비 대칭키 암호 방식

암호화된 통신을 할 두 사용자가 하나의 비밀키를 공유해야 하기 때문에 비밀키 전달 과정에서 키가 외부에 노출될 위험이 있다. 내 공개키를 상대방에게 알려주면 상대방은 공개키를 이용해 데이터를 암호화하고, 암호화된 데이터를 나에게 보낸다. 암호화된 데이터는 내가 갖고 있는 개인키를 이용해 복호화할 수 있다. 반대로 내가 상대방에게 데이터를 보낼 때는 상대방이 알려준 공개키를 이용해 암호화하고, 상대방은 자신이 갖은 비밀키를 사용해 복호화한다. 즉, 전달되는 것은 공개키 뿐인데 공개키 만으로는 데이터를 복호화할 수 없다. 비대칭키 암호의 대표적인 예로는 RSA, 타원 곡선 암호, 전자 서명 등이 있다.

AES를 알아보자

대표적으로 랜섬웨어에 사용되는 AES를 알아보고 사용해보자. AES는 Advanced Encryption Standard를 줄인 말이다. 한국어로 번역하면 ‘고급 암호화 표준’이다. 대칭키를 쓰는 블럭 암호이다. 높은 안전성과 속도로 인해 인기를 얻어 전 세계적으로 사용되고 있다.

자세한 알고리즘은 생략하고 주요한 용어와 사용방법을 설명한다.

IV(Initialization Vector)

Padding

Common modes

블록 암호는 특정한 길이의 블록 단위로 동작하기 때문에, 가변 길이 데이터를 암호화하기 위해서는 먼저 이들을 단위 블록들로 나누어야 하며, 그리고 그 블록들을 어떻게 암호화할지를 정해야 한다.

AES-CBC

import CryptoSwift

let input: Array<UInt8> = [0,1,2,3,4,5,6,7,8,9]
let key: Array<UInt8> = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
let iv: Array<UInt8> = AES.randomIV(AES.blockSize)

do {
    let encrypted = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).encrypt(input)
    let decrypted = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7).decrypt(encrypted)
} catch {
    print(error)
}    

AES-GCM

import CryptoSwift

let input: Array<UInt8> = [0,1,2,3,4,5,6,7,8,9]
let key: Array<UInt8> = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]
let iv: Array<UInt8> = AES.randomIV(AES.blockSize)

let retGCM = self.encryptABS_GCM(input: input, key: key, iv: iv)
print(retGCM.encrypted, retGCM.tag)
if let encrypted = retGCM.encrypted {
    let decrypt = decryptABS_GCM(encrypted: encrypted, key: key, iv: iv)
    print(decrypt)
}

func encryptABS_GCM(input:[UInt8], key:[UInt8], iv:[UInt8]) -> (encrypted:[UInt8]?, tag:[UInt8]?){
    do {
        let gcm = GCM(iv: iv, mode: .combined)
        let aes = try AES(key: key, blockMode: gcm, padding: .noPadding)
        let encrypted = try aes.encrypt(input)
        let tag = gcm.authenticationTag
        return (encrypted, tag)
    } catch let err {
        print(err.localizedDescription)
        return (nil, nil)
    }
}

func decryptABS_GCM(encrypted:[UInt8], key:[UInt8], iv:[UInt8]) -> [UInt8]? {
    do {
        let gcm = GCM(iv: iv, mode: .combined)
        let aes = try AES(key: key, blockMode: gcm, padding: .noPadding)
        let decrypt = try aes.decrypt(encrypted)
        return decrypt
    } catch let err {
        print(err.localizedDescription)
        return nil
    }
}

출처