투케이2K

162. (TWOK/UTIL) [Ios/Swift] C_JWE_Encryption_Module : JWE 웹 암호화 (JSON Web Encryption) 암복호화 클래스 본문

투케이2K 유틸파일

162. (TWOK/UTIL) [Ios/Swift] C_JWE_Encryption_Module : JWE 웹 암호화 (JSON Web Encryption) 암복호화 클래스

투케이2K 2025. 4. 6. 11:53

[설 명]

프로그램 : Ios / Swift

설 명 : C_JWE_Encryption_Module : JWE 웹 암호화 (JSON Web Encryption) 암복호화 클래스

 

[소스 코드]

import Foundation
import UIKit
import JOSESwift



class C_JWE_Encryption_Module: NSObject {
    
    

    /**
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * TODO [클래스 설명]
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 1. JSON 웹 암호화 (JSON Web Encryption, JWE) 암복호화 관련 클래스
     *
     * [JWT 구성 요소] :
     *
     *   >> 헤더 (header) : 알고리즘 , 토큰 사용에 대한 정보 (ex: 어떠한 토큰을 사용할 것 인지)
     *   >> 페이로드 (payload) : 전달하려는 정보 (사용자 ID, 토큰 발급일, 토큰 만료일, 기타 데이터 등)
     *   >> 서명 (signature) : 서버가 발급해준 비밀키로 헤더 , 페이로드 를 암호화시켜 토큰을 변조하기 어렵게 만듦
     *
     * [추가 정리]
     *
     *   >> TODO JWE 는 JWT 를 만드는 방법 중 하나입니다
     *   >> JWE 는 JSON 데이터를 암호화하여 기밀성을 보장하며, 암호화된 토큰은 데이터를 보호하고 인가된 수신자만이 내용을 볼 수 있도록 합니다
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 2. [설정 사항 및 라이브러리 필요]
     *
     * git 다운로드 주소 : https://github.com/airsidemobile/JOSESwift
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 3. [참고 사이트]
     *
     * [JWT 와 JSESSIONID 차이점 정리 - 액세스 인증 토큰 및 세션 아이디]
     *
     * https://blog.naver.com/kkh0977/223607055033?trackingCode=blog_bloghome_searchlist
     *
     *
     * [JWT (Json Web Token) AccessToken (액세스 토큰) 과 RefreshToken (리프래쉬 토큰) 갱신 및 업데이트 로직]
     *
     * https://blog.naver.com/kkh0977/223604705723?trackingCode=blog_bloghome_searchlist
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * 4. 필요 import :
     *
     * import JOSESwift
     * // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
     * */
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [전역 변수 선언]
    // -----------------------------------------------------------------------------------------
    public static let ACTIVITY_NAME = "C_JWE_Encryption_Module"
    
    private let AES128_GCM_KEY = "0123456789abcdef" // [16 바이트]
    private let AES192_GCM_KEY = "0123456789abcdef01234567" // [24 바이트]
    private let AES256_GCM_KEY = "0123456789abcdef0123456789abcdef" // [32 바이트]
    
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [AES GCM : JWE 인코딩 수행]
    // -----------------------------------------------------------------------------------------
    // TODO [Call Method]
    // ------------------------------------------------------------------------------------------
    /*
     DispatchQueue.main.async { // [비동기 요청]
         
         // [딕셔너리 선언]
         var dic : Dictionary<String, Any> = [String : Any]()
         dic["name"] = "Twok"
         dic["age"] = 30
         
         
         // [Dic To Json Stirng 변환]
         let jsonString = C_Util().dic_To_JsonObject_String(_dicData: dic)
         
         
         // [JWE 암호화 수행]
         let encode = C_JWE_Encryption_Module().encodeAes128GcmJwe(payload: jsonString)
     }
    */
    // ------------------------------------------------------------------------------------------
    func encodeAes128GcmJwe(payload: String) -> String {
        
        
        var returnData = "" // [Return 데이터]
        var M_LOG = "" // [Log 데이터]
        
        
        // -----------------------------------------------
        // TODO [1] : [key >> Byte 변환]
        // -----------------------------------------------
        let keyBytes = self.AES128_GCM_KEY.data(using: .utf8)!
        
        
        // -----------------------------------------------
        // TODO [2] : [JWE 헤더 설정 : A128GCM 사용]
        // -----------------------------------------------
        /**
         * {
         *   "cty": "application/json",
         *   "typ": "JWE",
         *   "enc": "A128GCM",
         *   "alg": "A128KW"
         * }
         */
        // -----------------------------------------------
        var header = JWEHeader(keyManagementAlgorithm: .A128KW, contentEncryptionAlgorithm: .A128GCM)
        header.typ = "JWE"
        header.cty = "application/json"

        
        // -----------------------------------------------
        // TODO [3] : [페이로드 지정]
        // -----------------------------------------------
        let message = payload.data(using: .utf8)!
        let payload_Object = Payload(message)
        
        
        // -----------------------------------------------
        // TODO [4] : [JWE 인코딩 수행 실시]
        // -----------------------------------------------
        let encrypter = Encrypter(keyManagementAlgorithm: .A128KW, contentEncryptionAlgorithm: .A128GCM, encryptionKey: keyBytes)!
        
        guard let jwe = try? JWE(header: header, payload: payload_Object, encrypter: encrypter)
        else {
            M_LOG = "Error :: JWE Encode Error"
            
            S_Log._E_(description: C_JWE_Encryption_Module.ACTIVITY_NAME + " :: encodeAes128GcmJwe :: JWE 인코딩 실패", data: [
                "M_LOG :: \(M_LOG)",
                "RETURN :: \(returnData)"
            ])
            
            return returnData
        }
        
        
        // -----------------------------------------------
        // TODO [5] : [리턴 정보 확인]
        // -----------------------------------------------
        returnData = jwe.compactSerializedString // [base64 데이터]
        M_LOG = "Success :: JWE Encode"
        
        
        S_Log._D_(description: C_JWE_Encryption_Module.ACTIVITY_NAME + " :: encodeAes128GcmJwe :: JWE 인코딩 수행", data: [
            "M_LOG :: \(M_LOG)",
            "RETURN :: \(returnData)"
        ])
        
        
        return returnData
        
    }
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [AES GCM : JWE 디코딩 수행]
    // -----------------------------------------------------------------------------------------
    // TODO [Call Method]
    // ------------------------------------------------------------------------------------------
    /*
     DispatchQueue.main.async { // [비동기 요청]
         
         // [JWE 복호화 수행]
         let jweString = "eyJhbGciOiJBMTI4S1ciLCJjdHkiOiJhcHBsaWNhdGlvblwvanNvbiIsImVuYyI6IkExMjhHQ00iLCJ0eXAiOiJKV0UifQ.sVN3ew9v18jPSWrMAuLMcCjwhXgtqJMy.OSI_gsoMVsOZejdU.Cd1ZwL5uUczqrm1BnHdhSIyup-QsbPA49YgGBFqwEJ2XNjM.y0FePKGFEKCVaYFUaFqxdg"
         
         let decode = C_JWE_Encryption_Module().decodeAes128GcmJwe(jweString: jweString)
         
     }
    */
    // ------------------------------------------------------------------------------------------
    func decodeAes128GcmJwe(jweString: String) -> String {
        
        
        var returnData = "" // [Return 데이터]
        var M_LOG = "" // [Log 데이터]
        
        
        // -----------------------------------------------
        // TODO [1] : [key >> Byte 변환]
        // -----------------------------------------------
        let keyBytes = self.AES128_GCM_KEY.data(using: .utf8)!
        
        
        // -----------------------------------------------
        // TODO [2] : [디코딩 수행 실시]
        // -----------------------------------------------
        if C_Util().stringNotNull(str: jweString) == true {
            
            do {
             
                let jwe = try JWE(compactSerialization: jweString)
                
                let decrypter = Decrypter(keyManagementAlgorithm: .A128KW, contentEncryptionAlgorithm: .A128GCM, decryptionKey: keyBytes)!
                
                let payload = try jwe.decrypt(using: decrypter)
                
                let message = String(data: payload.data(), encoding: .utf8)!
                
                returnData = message // [리턴 변수 삽입]
                M_LOG = "Success :: JWE Decode"
                
            }
            catch {
                M_LOG = "Exception :: \(error)"
            }
            
        }
        else {
            M_LOG = "Error :: JWE String Is Null"
        }
        
        
        S_Log._D_(description: C_JWE_Encryption_Module.ACTIVITY_NAME + " :: decodeAes128GcmJwe :: JWE 디코딩 수행", data: [
            "M_LOG :: \(M_LOG)",
            "RETURN :: \(returnData)"
        ])
        
        
        return returnData
        
    }
    
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [AES GCM : JWE 인코딩 수행]
    // -----------------------------------------------------------------------------------------
    // TODO [Call Method]
    // ------------------------------------------------------------------------------------------
    /*
     DispatchQueue.main.async { // [비동기 요청]
         
         // [딕셔너리 선언]
         var dic : Dictionary<String, Any> = [String : Any]()
         dic["name"] = "Twok"
         dic["age"] = 30
         
         
         // [Dic To Json Stirng 변환]
         let jsonString = C_Util().dic_To_JsonObject_String(_dicData: dic)
         
         
         // [JWE 암호화 수행]
         let encode = C_JWE_Encryption_Module().encodeAes192GcmJwe(payload: jsonString)
     }
    */
    // ------------------------------------------------------------------------------------------
    func encodeAes192GcmJwe(payload: String) -> String {
        
        
        var returnData = "" // [Return 데이터]
        var M_LOG = "" // [Log 데이터]
        
        
        // -----------------------------------------------
        // TODO [1] : [key >> Byte 변환]
        // -----------------------------------------------
        let keyBytes = self.AES192_GCM_KEY.data(using: .utf8)!
        
        
        // -----------------------------------------------
        // TODO [2] : [JWE 헤더 설정 : A192GCM 사용]
        // -----------------------------------------------
        /**
         * {
         *   "cty": "application/json",
         *   "typ": "JWE",
         *   "enc": "A192GCM",
         *   "alg": "A192KW"
         * }
         */
        // -----------------------------------------------
        var header = JWEHeader(keyManagementAlgorithm: .A192KW, contentEncryptionAlgorithm: .A192GCM)
        header.typ = "JWE"
        header.cty = "application/json"

        
        // -----------------------------------------------
        // TODO [3] : [페이로드 지정]
        // -----------------------------------------------
        let message = payload.data(using: .utf8)!
        let payload_Object = Payload(message)
        
        
        // -----------------------------------------------
        // TODO [4] : [JWE 인코딩 수행 실시]
        // -----------------------------------------------
        let encrypter = Encrypter(keyManagementAlgorithm: .A192KW, contentEncryptionAlgorithm: .A192GCM, encryptionKey: keyBytes)!
        
        guard let jwe = try? JWE(header: header, payload: payload_Object, encrypter: encrypter)
        else {
            M_LOG = "Error :: JWE Encode Error"
            
            S_Log._E_(description: C_JWE_Encryption_Module.ACTIVITY_NAME + " :: encodeAes192GcmJwe :: JWE 인코딩 실패", data: [
                "M_LOG :: \(M_LOG)",
                "RETURN :: \(returnData)"
            ])
            
            return returnData
        }
        
        
        // -----------------------------------------------
        // TODO [5] : [리턴 정보 확인]
        // -----------------------------------------------
        returnData = jwe.compactSerializedString // [base64 데이터]
        M_LOG = "Success :: JWE Encode"
        
        
        S_Log._D_(description: C_JWE_Encryption_Module.ACTIVITY_NAME + " :: encodeAes192GcmJwe :: JWE 인코딩 수행", data: [
            "M_LOG :: \(M_LOG)",
            "RETURN :: \(returnData)"
        ])
        
        
        return returnData
        
    }
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [AES GCM : JWE 디코딩 수행]
    // -----------------------------------------------------------------------------------------
    // TODO [Call Method]
    // ------------------------------------------------------------------------------------------
    /*
     DispatchQueue.main.async { // [비동기 요청]
         
         // [JWE 복호화 수행]
         let jweString = "eyJhbGciOiJBMTkyS1ciLCJjdHkiOiJhcHBsaWNhdGlvblwvanNvbiIsImVuYyI6IkExOTJHQ00iLCJ0eXAiOiJKV0UifQ.SK5Pdd7rZdpFnPxcHxC0-GcUu8PFfsNSD4V9NH_lo90.wVrnWT5jWVlESjlG.28JDcM2zLhasuqkCoUmVV2VYEVsU_06pl6doePJ9Iur1_Bs.VrRjkx3iJNkt_fQYJzQVbg"
         
         let decode = C_JWE_Encryption_Module().decodeAes192GcmJwe(jweString: jweString)
         
     }
    */
    // ------------------------------------------------------------------------------------------
    func decodeAes192GcmJwe(jweString: String) -> String {
        
        
        var returnData = "" // [Return 데이터]
        var M_LOG = "" // [Log 데이터]
        
        
        // -----------------------------------------------
        // TODO [1] : [key >> Byte 변환]
        // -----------------------------------------------
        let keyBytes = self.AES192_GCM_KEY.data(using: .utf8)!
        
        
        // -----------------------------------------------
        // TODO [2] : [디코딩 수행 실시]
        // -----------------------------------------------
        if C_Util().stringNotNull(str: jweString) == true {
            
            do {
             
                let jwe = try JWE(compactSerialization: jweString)
                
                let decrypter = Decrypter(keyManagementAlgorithm: .A192KW, contentEncryptionAlgorithm: .A192GCM, decryptionKey: keyBytes)!
                
                let payload = try jwe.decrypt(using: decrypter)
                
                let message = String(data: payload.data(), encoding: .utf8)!
                
                returnData = message // [리턴 변수 삽입]
                M_LOG = "Success :: JWE Decode"
                
            }
            catch {
                M_LOG = "Exception :: \(error)"
            }
            
        }
        else {
            M_LOG = "Error :: JWE String Is Null"
        }
        
        
        S_Log._D_(description: C_JWE_Encryption_Module.ACTIVITY_NAME + " :: decodeAes192GcmJwe :: JWE 디코딩 수행", data: [
            "M_LOG :: \(M_LOG)",
            "RETURN :: \(returnData)"
        ])
        
        
        return returnData
        
    }
    
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [AES GCM : JWE 인코딩 수행]
    // -----------------------------------------------------------------------------------------
    // TODO [Call Method]
    // ------------------------------------------------------------------------------------------
    /*
     DispatchQueue.main.async { // [비동기 요청]
         
         // [딕셔너리 선언]
         var dic : Dictionary<String, Any> = [String : Any]()
         dic["name"] = "Twok"
         dic["age"] = 30
         
         
         // [Dic To Json Stirng 변환]
         let jsonString = C_Util().dic_To_JsonObject_String(_dicData: dic)
         
         
         // [JWE 암호화 수행]
         let encode = C_JWE_Encryption_Module().encodeAes256GcmJwe(payload: jsonString)
     }
    */
    // ------------------------------------------------------------------------------------------
    func encodeAes256GcmJwe(payload: String) -> String {
        
        
        var returnData = "" // [Return 데이터]
        var M_LOG = "" // [Log 데이터]
        
        
        // -----------------------------------------------
        // TODO [1] : [key >> Byte 변환]
        // -----------------------------------------------
        let keyBytes = self.AES256_GCM_KEY.data(using: .utf8)!
        
        
        // -----------------------------------------------
        // TODO [2] : [JWE 헤더 설정 : A256GCM 사용]
        // -----------------------------------------------
        /**
         * {
         *   "cty": "application/json",
         *   "typ": "JWE",
         *   "enc": "A256GCM",
         *   "alg": "A256KW"
         * }
         */
        // -----------------------------------------------
        var header = JWEHeader(keyManagementAlgorithm: .A256KW, contentEncryptionAlgorithm: .A256GCM)
        header.typ = "JWE"
        header.cty = "application/json"

        
        // -----------------------------------------------
        // TODO [3] : [페이로드 지정]
        // -----------------------------------------------
        let message = payload.data(using: .utf8)!
        let payload_Object = Payload(message)
        
        
        // -----------------------------------------------
        // TODO [4] : [JWE 인코딩 수행 실시]
        // -----------------------------------------------
        let encrypter = Encrypter(keyManagementAlgorithm: .A256KW, contentEncryptionAlgorithm: .A256GCM, encryptionKey: keyBytes)!
        
        guard let jwe = try? JWE(header: header, payload: payload_Object, encrypter: encrypter)
        else {
            M_LOG = "Error :: JWE Encode Error"
            
            S_Log._E_(description: C_JWE_Encryption_Module.ACTIVITY_NAME + " :: encodeAes256GcmJwe :: JWE 인코딩 실패", data: [
                "M_LOG :: \(M_LOG)",
                "RETURN :: \(returnData)"
            ])
            
            return returnData
        }
        
        
        // -----------------------------------------------
        // TODO [5] : [리턴 정보 확인]
        // -----------------------------------------------
        returnData = jwe.compactSerializedString // [base64 데이터]
        M_LOG = "Success :: JWE Encode"
        
        
        S_Log._D_(description: C_JWE_Encryption_Module.ACTIVITY_NAME + " :: encodeAes256GcmJwe :: JWE 인코딩 수행", data: [
            "M_LOG :: \(M_LOG)",
            "RETURN :: \(returnData)"
        ])
        
        
        return returnData
        
    }
    
    
    
    
    
    // -----------------------------------------------------------------------------------------
    // MARK: - [AES GCM : JWE 디코딩 수행]
    // -----------------------------------------------------------------------------------------
    // TODO [Call Method]
    // ------------------------------------------------------------------------------------------
    /*
     DispatchQueue.main.async { // [비동기 요청]
         
         // [JWE 복호화 수행]
         let jweString = "eyJhbGciOiJBMjU2S1ciLCJjdHkiOiJhcHBsaWNhdGlvblwvanNvbiIsImVuYyI6IkEyNTZHQ00iLCJ0eXAiOiJKV0UifQ.tf80F7VQqUpHBZiodKi-ShEmC3B7NUtPPsGg4YTzFGN2qK0I0WNV5A.NFTw2bmNs1E5pwyf.Z13WdkVrNFQBLAixzMKp5uLo6APvJIX3le-9p6jhuH5QlVY.NlQ9A5KgOByBSGs0f81xPw"
         
         let decode = C_JWE_Encryption_Module().decodeAes256GcmJwe(jweString: jweString)
         
     }
    */
    // ------------------------------------------------------------------------------------------
    func decodeAes256GcmJwe(jweString: String) -> String {
        
        
        var returnData = "" // [Return 데이터]
        var M_LOG = "" // [Log 데이터]
        
        
        // -----------------------------------------------
        // TODO [1] : [key >> Byte 변환]
        // -----------------------------------------------
        let keyBytes = self.AES256_GCM_KEY.data(using: .utf8)!
        
        
        // -----------------------------------------------
        // TODO [2] : [디코딩 수행 실시]
        // -----------------------------------------------
        if C_Util().stringNotNull(str: jweString) == true {
            
            do {
             
                let jwe = try JWE(compactSerialization: jweString)
                
                let decrypter = Decrypter(keyManagementAlgorithm: .A256KW, contentEncryptionAlgorithm: .A256GCM, decryptionKey: keyBytes)!
                
                let payload = try jwe.decrypt(using: decrypter)
                
                let message = String(data: payload.data(), encoding: .utf8)!
                
                returnData = message // [리턴 변수 삽입]
                M_LOG = "Success :: JWE Decode"
                
            }
            catch {
                M_LOG = "Exception :: \(error)"
            }
            
        }
        else {
            M_LOG = "Error :: JWE String Is Null"
        }
        
        
        S_Log._D_(description: C_JWE_Encryption_Module.ACTIVITY_NAME + " :: decodeAes256GcmJwe :: JWE 디코딩 수행", data: [
            "M_LOG :: \(M_LOG)",
            "RETURN :: \(returnData)"
        ])
        
        
        return returnData
        
    }
    
    
} // [클래스 종료]
 
반응형
Comments