기본 콘텐츠로 건너뛰기

개발 공부 - Base64 인코딩/디코딩 시 패딩 제거 문제 (Standard Base64)

Base64 인코딩 / 디코딩시 동일하게 풀리지 않는 문제가 있어서 함수를 사용하는 예제를 만들어 봤다.

자바에서 다시 인코딩할 때는 base64Compare함수처럼 사용해야 원하는 결과값을 얻을 수 있다.

회사에서 사용할 때 결과값이 이상해서 만들어 봤으나, 요청사항 내에 encodeBase64URLSafeString 쓰라는 API 문서가 있어서 요청한 대로 적용할 예정이다.


https://www.python2.net/questions-665529.htm 에서 찾아낸 것과 같이,

org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString(aByteArray); 

  URL 안전 base64 변형을 만듭니다. (인코딩의 일부로 _ 및-사용)

java.util.Base64.getEncoder().encodeToString(aByteArray); 

인코딩의 일부로 "/" "="및 "+"를 사용하여 "standard"base64를 만듭니다. URL 안전하지 않습니다.


인코딩의 안전성을 위해 encodeBase64URLSafeString을 권장하는 듯 하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import org.apache.tomcat.util.codec.binary.Base64;
 
public class base64CompareExample {
    
    public static boolean base64Compare(String b64String) {
        //b64String : urlSafe로 인코딩된 문자열
            
        boolean flag = false;
 
        byte[] oriBytes = Base64.decodeBase64(b64String); //복원
        String recoverString = Base64.encodeBase64String(oriBytes); //재인코딩
 
        if(b64String.equals(recoverString)) {
            flag = true;
        }
        
        return flag;
    }
    public static boolean base64CompareSafe(String b64String) {
        //b64String : urlSafe로 인코딩된 문자열
            
        boolean flag = false;
 
        byte[] oriBytes = Base64.decodeBase64(b64String); //복원
        String recoverString = Base64.encodeBase64URLSafeString(oriBytes); //재인코딩
        
        if(b64String.equals(recoverString)) {
            flag = true;
        }
        
        return flag;
    }
    
    public static void main(String[] args) throws Exception{
        //BASE64 패딩 문제로 == 날아가는 경우 때문에 
        //https://m.blog.naver.com/kh2un/220948253486 참고해서 적용해 봄
 
        String b64String = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEB0V9gbnwHVgWGrVDZv8Ja2FFsPU2yqV2DS+/wQz+74Ccbqzt/onGZAf/Jl6IOyyzH0qmY1Jbex+nkt+i1PjgIg==";
        System.out.println("Base64.encodeBase64URLSafeString 복원 : " + base64CompareSafe(b64String));
        System.out.println("Base64.encodeBase64String        복원  : " + base64Compare(b64String));
        
    }
    
    
}
 
 
cs

결과값은 

Base64.encodeBase64URLSafeString 복원 : false
Base64.encodeBase64String        복원  : true

이런 식으로 나오니, 내가 다시 Standard 형태의 Base64를 사용하고 싶을 때에는 
Base64.getEncoder().encodeToString 이나 Base64.encodeBase64String 을 사용할 것이다.



* JWT 관련 검색 하다가 추가

[Base64 URL-Safe != Base64]

Base64 URL-Safe 인코딩은 기본 Base64 인코딩에서 '+'(plus)는 '-'(minus)로, '/'(slash)는 '_'(underscore)로 대체된 인코딩 방법이다. 
이로 인해서 JWT는 설계 의도대로 URL, Cookie, Header 등 어디에서도 사용될 수 있는 넓은 범용성을 가지게 되었다.

= URL로 사용할 경우에는 '/'가 분리자로 사용되기 때문에 '_'와 같이 URL에 방해되지 않는 요소로 대체하여 사용해야 하는데, SAFE 요소를 추가하면 이와 같이 동작한다.

요청 사항에 들어있던 이유도 위와 같은 사유 때문인 것으로 깨달음을 얻었다.

댓글