투케이2K

974. (Android/Java) [nimbusds] JWE AES GCM 인코딩 수행 시 ObjectMapper 사용해 Payload 페이로드 매핑 방법 본문

Android

974. (Android/Java) [nimbusds] JWE AES GCM 인코딩 수행 시 ObjectMapper 사용해 Payload 페이로드 매핑 방법

투케이2K 2025. 4. 20. 18:36

[개발 환경 설정]

개발 툴 : AndroidStudio

개발 언어 : Java / Kotlin

 

[소스 코드]

 

// --------------------------------------------------------------------------------------
[개발 및 테스트 환경]
// --------------------------------------------------------------------------------------

- 언어 : Java / Kotlin

- 개발 툴 : AndroidStudio

- 기술 구분 : nimbusds / JWE / JWT / AES

// --------------------------------------------------------------------------------------






// --------------------------------------------------------------------------------------
[nimbusds 라이브러리 의존성 부여 설정 : build.gradle]
// --------------------------------------------------------------------------------------

// TODO [JWE 암복호화 관련]
implementation 'com.nimbusds:nimbus-jose-jwt:10.0.2'


// TODO [jackson 라이브러리 추가]
implementation 'com.fasterxml.jackson.core:jackson-core:2.13.4'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.4'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4'

// --------------------------------------------------------------------------------------






// --------------------------------------------------------------------------------------
[Java : 소스 코드]
// --------------------------------------------------------------------------------------

// --------------------------------------------------------------------
// TODO [전역 변수 선언]
// --------------------------------------------------------------------
private static final String AES128_GCM_KEY = "0123456789abcdef"; // [16 바이트]




// --------------------------------------------------------------------
// TODO [AES GCM : JWE 인코딩 수행]
// --------------------------------------------------------------------
// TODO [Call Method]
// --------------------------------------------------------------------
/*
User_Module userPerson = new User_Module(
        "APP", // [발급자]
        "TWOK2K", // [아이디]
        "투케이", // [이름]
        Integer.parseInt(nowTimeStamp.substring(0,10)), // [발급 시간]
        Integer.parseInt(afterTimeStamp.substring(0,10)) // [만료 시간]
);

ObjectMapper objectMapper = new ObjectMapper();
String jsonData = objectMapper.writeValueAsString(userPerson);

C_JWE_Encryption_Module.encodeAes128GcmJwe(jsonData);
*/
// --------------------------------------------------------------------
public static String encodeAes128GcmJwe(String payload){

    String returnData = null; // [Return 데이터]
    String M_LOG = null; // [Log 데이터]

    try {

        // -----------------------------------------------
        // TODO [1] : [key >> Byte 변환]
        // -----------------------------------------------
        byte keyBytes [] = AES128_GCM_KEY.getBytes(StandardCharsets.UTF_8);


        // -----------------------------------------------
        // TODO [2] : [SecretKey 가져오기]
        // -----------------------------------------------
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");


        // -----------------------------------------------
        // TODO [3] : [JWE 헤더 설정 : A128GCM 사용]
        // -----------------------------------------------
        /**
          * {
          *   "cty": "application/json",
          *   "typ": "JWE",
          *   "enc": "A128GCM",
          *   "tag": "SddQInhWp2DFzVFtMEDcSw", ------------> Random : 무결성 검증 Auth Tag 자동 생성
          *   "alg": "A128GCMKW",
          *   "iv": "qBQizBH5fvDRjgj_" --------------------> Random : 암호화 과정에서 사용된 초기화 벡터
          * }
        */
        // -----------------------------------------------
        JWEHeader header = new JWEHeader.Builder(
                JWEAlgorithm.A128GCMKW, // TODO [alg : 알고 리즘]
                EncryptionMethod.A128GCM) // TODO [enc : 인코딩 타입]
                .type(new JOSEObjectType("JWE")) // TODO [typ : 타입]
                .contentType("application/json") // TODO [cty : 컨텐츠 타입]
                .build();


        // -----------------------------------------------
        // TODO [4] : [페이로드 지정] : App To Server 서로 협의 후 전송 형태 정의
        // -----------------------------------------------
        // Payload payload_Object = new Payload(payload); // [Payload : String]


        // -----------------------------------------------
        // TODO [5] : [JWEObject 생성] / [인코딩 수행 실시]
        // -----------------------------------------------
        JWEObject jweObject = new JWEObject(header, payload_Object);

        //jweObject.encrypt(new DirectEncrypter(secretKeySpec)); // TODO [알고리즘 : DIR]
        jweObject.encrypt(new AESEncrypter(secretKeySpec)); // TODO [알고리즘 : JWEAlgorithm.A128GCMKW]

        S_Log._D_(ACTIVITY_NAME + " :: encodeAes128GcmJwe :: JWEObject 정보 확인", new String[]{
                "getHeader :: " + jweObject.getHeader(),
                "getEncryptedKey :: " + jweObject.getEncryptedKey(),
                "getCipherText :: " + jweObject.getCipherText(),
                "getIV :: " + jweObject.getIV(),
                "getAuthTag :: " + jweObject.getAuthTag(),
                "getState :: " + jweObject.getState()
        });

        String jweString = jweObject.serialize(); // TODO [JWE Encode String]


        // -----------------------------------------------
        // TODO [6] : [JWE 토큰 널 체크 수행]
        // -----------------------------------------------
        if (C_Util.stringNotNull(jweString) == true){
            returnData = jweString;
        }
        else {
            M_LOG = "Error : jweString Is Null";
        }

    }
    catch (Exception e){
        e.printStackTrace();

        M_LOG = "Exception : " + e.getMessage();
    }


    try { M_LOG = (M_LOG != null) ? M_LOG : ( (returnData != null) ? "Encode :: " + returnData : "Encode :: null" ); } catch (Exception el){}

    S_Log._D_(ACTIVITY_NAME + " :: encodeAes128GcmJwe :: JWE 인코딩 수행", new String[]{"KEY :: " + AES128_GCM_KEY, String.valueOf(M_LOG)});


    return returnData;

}




// --------------------------------------------------------------------
// TODO [매퍼 클래스 생성]
// --------------------------------------------------------------------
package com.example.javaproject.C_Module;

public class User_Module {


    /**
     * // --------------------------------------------------------------------------------------
     * TODO [클래스 설명]
     * // --------------------------------------------------------------------------------------
     * 1. TODO [설명] : JWE 인코딩에 사용 되는 매퍼 클래스
     * // --------------------------------------------------------------------------------------
     * */





    // ------------------------------------------------------------------------------------------
    // TODO [전역 변수 선언]
    // ------------------------------------------------------------------------------------------
    private String iss; // [발급자]
    private String userId; // [아이디]
    private String userName; // [이름]
    private int iat; // [발급 시간] : 10 자리 타임 스탬프
    private int exp; // [만료 시간] : 10 자리 타임 스탬프





    // ------------------------------------------------------------------------------------------
    // TODO [클래스 생성자 초기화]
    // ------------------------------------------------------------------------------------------
    public User_Module(String iss, String userId, String userName, int iat, int exp) {
        this.iss = iss;
        this.userId = userId;
        this.userName = userName;
        this.iat = iat;
        this.exp = exp;
    }



    // ------------------------------------------------------------------------------------------
    // TODO [Get 정의]
    // ------------------------------------------------------------------------------------------
    public String getIss() {
        return iss;
    }

    public String getUserId() {
        return userId;
    }

    public String getUserName() {
        return userName;
    }

    public int getIat() {
        return iat;
    }

    public int getExp() {
        return exp;
    }



    // ------------------------------------------------------------------------------------------
    // TODO [Set 정의]
    // ------------------------------------------------------------------------------------------
    public void setIss(String iss) {
        this.iss = iss;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setIat(int iat) {
        this.iat = iat;
    }

    public void setExp(int exp) {
        this.exp = exp;
    }


} // TODO [클래스 종료]

// --------------------------------------------------------------------------------------





// --------------------------------------------------------------------------------------
[참고 사이트]
// --------------------------------------------------------------------------------------

[온라인 JWT 토큰 복호화 및 헤더 값 확인 참고 사이트]

https://fusionauth.io/dev-tools/jwt-decoder


[라이브러리] [nimbus-jose-jwt] JWE (JSON Web Encryption) JSON 웹 암호화 및 복호화 라이브러리

https://blog.naver.com/kkh0977/223817959400?trackingCode=blog_bloghome_searchlist


[JWT (Json Web Token) 개념 설명]

https://blog.naver.com/kkh0977/222934042760?trackingCode=blog_bloghome_searchlist


[JWE (JSON Web Encryption) JSON 웹 암호화 설명]

https://blog.naver.com/kkh0977/223817878517?trackingCode=blog_bloghome_searchlist

// --------------------------------------------------------------------------------------

[참고 사이트]

 

https://blog.naver.com/kkh0977/223817959400?trackingCode=blog_bloghome_searchlist

 

110. (Library/Framework) [라이브러리] [Android] JWE (JSON Web Encryption) 웹 암복호화 라이브러리 - nimbus-jose-jw

[타이틀] 구 분 : Library / 라이브러리 제 목 : [라이브러리] [Android] JWE (JSON Web Encryp...

blog.naver.com


반응형
Comments