회사 프로젝트에서 AES-256암호화로 웹과 데이터를 주고받아야 하는 일이 있었다.
서버: App으로 광고 전달
App: 특정 조건에 해당하는 경우 사용자 정보를 암호화하고 내부 규정에 맞춰 웹으로 이동시키는 작업
이 경우 웹으로 이동 시 사용자 정보를 함께 전달해야 하므로 AES-256으로 암호화 하고 서버는 웹으로 전달받은 내용을 복호화 하여 데이터 처리
우선 AES암호화는 양방향 암호화입니다.
단방향 암호화: 한 번 암호화하면 원래 데이터로 되돌릴 수 없는 암호화 방식입니다. 주로 해시함수를 사용하여 데이터를 특정 길이의 고정된 데이터로 변환합니다 대표적으로 SHA-256기법이 있습니다. 복호화가 불가능하다는 특징이 있으며 주로 비밀번호 저장, 파일 무결성 체크에 사용됩니다.
양방향 암호화: 암호화된 데이터를 필요할 때 복구하여 사용할 수 있는 경우에 유용합니다. 키의 보안성이 아주 중요하며 키가 유출되면 암호화된 데이터도 쉽게 복호화 할 수 있습니다. AES-256이 있습니다.
AES-256의 특징
1. 대칭키 암호화: 암호화와 복호화에 동일한 키를 사용합니다.
- 암호화할 때 사용한 비밀키를 유출하게 되면 보안이 취약해질 수 잇습니다
2. 256비트 키 사용
- AES알고리즘은 128, 192, 256비트의 키 길이를 사용할 수 있습니다. 이 중 AES256은 가장 긴 키 길이를 사용하여 보안 강도가 가장 높습니다.
3. 고속성과 보안성
- 블록 암호 방식중에서 상대적으로 빠른 속도를 제공하며 256비트 키 길이는 현재까지 알려진 모든 공격 기법에 대해 안전한 수준이라고 합니다.
동작원리
AES256은 블록 암호화 방식을 사용하여 데이터를 암호화 합니다. 즉 데이터를 128비트(16바이트)크기의 블록 단위로 나누어 각 블록을 암호화합니다.
1. 키 생성: 256비트의 비밀키를 생성합니다
2. 암호화 과정: AES256 암호화는 10, 12, 14라운드로 반복되며 각 라운드는 4가지 연산으로 구성됩니다.
• SubBytes: 각 바이트를 S-box라고 불리는 표를 통해 대체하여 비선형 변환을 수행합니다.
• ShiftRows: 행을 기준으로 각 바이트를 좌측으로 이동하여 데이터를 재배열합니다.
• MixColumns: 열을 기준으로 행렬 곱셈을 수행하여 행 간 상호작용을 증가시킵니다.
• AddRoundKey: 라운드 키와 XOR 연산을 수행하여 블록 데이터를 섞습니다.
3. 복호화 과정: 복호화는 암호화의 역순으로 수행됩니다.
모드의 종류
1. ECB (Electronic Codebook Mode):
• 동일한 평문 블록이 동일한 암호문 블록으로 암호화되므로, 패턴 노출의 위험이 큽니다.
• 데이터 양이 작을 때나 성능이 중요한 경우에 사용됩니다.
2. CBC (Cipher Block Chaining Mode):
• 각 블록을 암호화하기 전에 이전 블록의 암호문과 XOR 연산을 수행합니다.
• *초기화 벡터(IV)가 필요하며, 평문의 변화가 암호문 전체에 영향을 미치므로 보안성이 더 높습니다.
3. CFB (Cipher Feedback Mode):
• 스트림 암호처럼 동작하며, 실시간 데이터 암호화에 적합합니다.
4. OFB (Output Feedback Mode):
• 비트 오류가 전체 암호문에 영향을 주지 않도록 설계되었으며, 스트림 암호와 유사한 방식입니다.
5. GCM (Galois/Counter Mode):
• 데이터 무결성을 제공하는 인증 모드입니다. 빠른 속도와 높은 보안성을 제공하여 많이 사용됩니다.
사용시 유의할 점
1. 키 관리: AES256의 보안 강도는 키의 안전한 관리에 따라 결정됩니다. 키가 유출되면 암호화의 의미가 없습니다.
2. 초기화 벡터(IV): CBC모드와 같은 경우 IV가 필요합니다. IV는 키와 함께 안전하게 관리되어야 합니다.
3. 패딩(padding): AES256은 고정 블록 크기(16바이트)로 암호화 하므로 평분의 길이가 16배수가 아닌 경우 패딩을 추가해야합니다.
AES256은 현재로서는 가장 안전하고 널리 사용되는 대칭키 암호화 방식이라고 합니다. 데이터의 기밀성을 보장하는데 매우 효과적이지만 키 관리와 초기화 벡터의 적절한 사용이 중요합니다.
import CryptoSwift
public class AES256Cryption {
private static let SECRET_KEY = "15647894536123156489496543213153"
private static let IV = "asdfasvzxcvasdff"
static func encrypt(string: String) throws -> String {
guard !string.isEmpty else { return "" }
return try getAESObject().encrypt(string.bytes).toBase64()
}
static func decrypt(string: String) throws -> String {
guard !string.isEmpty else { return "" }
let data = Data(base64Encoded: string)
let decrypted = try getAESObject().decrypt([UInt8](data!))
return String(bytes: decrypted, encoding: .utf8) ?? ""
}
private static func getAESObject() throws -> AES {
let keyDecodes: Array<UInt8> = Array(SECRET_KEY.utf8)
let ivDecodes: Array<UInt8> = Array(IV.utf8)
let aesObject = try AES(key: keyDecodes, blockMode: CBC(iv: ivDecodes), padding: .pkcs5)
return aesObject
}
}
AES256으로 "Hello, world!"을 암호화 한 결과입니다.
CryptoSwift
https://github.com/krzyzanowskim/CryptoSwift