반응형

HMAC(Hash-based Message Authentication Code)

메시지 인증 코드(Message Authentication Code, MAC)는 메시지의 인증에 쓰이는 정보(코드)이다. 메시지의 무결성 및 신뢰성을 보장하는 용도로 MAC을 사용한다.

무결성이란, 서버 입장에서 클라이언트로부터 API 요청을 받았을 때, 이 요청이 신뢰할 수 있는 것인지 (정보가 중간에 변경없이 그대로 전달된 것인지)에 대한 성질을 말한다.

 

HMAC은 인증을 위한 Secret Key와 임의의 길이를 가진 Message를 해시 함수(알고리즘)을 사용해서 생성한다. 해시 함수로는 MD5, SHA-256과 같은 일반적인 해시 함수를 그대로 사용할 수 있으며 각 알고리즘에 따라 다른 고정길이의 MAC(Hash value)가 생성된다.

- Secret Key: 서버와 클라이언트가 함께 알고 있는 외부로 유출되어서는 안되는 값.

- Message: 클라이언트가 전송하는 요청의 전체(Header + Body)가 될 수도 있고, URL만 될 수도 있다.

 

여기까지가 일반적인 HMAC에 대한 정의이고, 위의 내용만 보면 이해가 쉽지 않아 아래에 좀 더 쉽게 설명하자면,

HMAC은 해싱기법을 이용해서 메시지의 위변조가 있었는지 체크하는 인증 기법이다.

해싱 자체는 원문 메시지를 일정한 길이의 다른 메시지로 변환하되, 일정 길이로 떨어지게 하는 기법. 원문을 해싱하여 나온 메시지를 다이제스트 라고 한다.

해싱의 결과는 유일하고(즉, A를 언제든 같은 해싱 기법으로 변환하면 항상 A' 가 된다), 해싱을 풀어 원문을 찾아낼 수 없다는 것이 장점.

 

HMAC으로 메세지 위변조 감지 절차

1. 메시지 보내는 쪽과 받는 쪽을 가정하고 이 둘은 두 가지를 공통적으로 알고 있어야한다.  그리고 어떤 HMAC 알고리즘 사용할지.(HMAC의 종류가 다양하므로) HMAC-SHA256 알고리즘을 사용한다고 가정한다면(그림에서 HMAC-SHA256 알고리즘은 암호화 알고리즘이 아님)

2. 보내는 쪽에서 보내고 싶은 내용이 있고, 그리고 공통의 KEY(SecretKey)가 있다. 이를 사용해서 보내는 쪽에서 시그니처 Signature라는 것을 생성하는데, 이 값은 메시지의 hash 값이다. KEY와 내용을 HASH 알고리즘에 적용하면, 시그니처가 생성된다.

 

3. 받는 쪽에서도 KEY(SecretKey)를 알고 있고 알고리즘도 알고 있다. 받는 쪽에서도 똑같이 Signature를 만든 후, 이를 받은 Signature와 맞는지 검증한다.

 

4. 중간에 메시지가 위조되었다면, "보낸 시점의 메시지와 받은 시점의 메시지가 다르니까 signature도 다르게 나올것이다." 라는 것이 HMAC의 컨셉이다.만약 signature까지 위조하려고 해도, 위조자는 KEY 값을 모르니까 위조할 수 없다는 점이 HMAC의 장점.

HMAC-SHA256에서 SHA-256은?SHA- 시리즈들은 Secure Hash Algorithm 이라는 이름으로, 해시 알고리즘의 종류들을 말한다. SHA-1, SHA-2 .. 등이 있는데, 중간에 모든 숫자가 있는 건 아니다. SHA-2 는 다이제스트의 길이가 다양한데, 이 중 다이제스트의 길이가 256byte인 것을 SHA-256이라고 한다.

반응형

'Tech develop > 인증' 카테고리의 다른 글

RSA 암호 알고리즘이란?  (0) 2021.07.29
블록 암호화에서의 운영 모드 및 패딩  (0) 2021.07.29
[Android] WhiteBox  (0) 2021.07.29
Android KeyStore 와 Keystore 의 차이  (0) 2021.07.29
,
반응형

RSA 암호 알고리즘이란?

Rivet, Shamir, Adelman 세사람의 첫이름을 따 RSA라고 만든 암호 알고리즘이다.

RSA 암호 체계는 미국 MIT에서 개발한 공개키 암호 시스템이다.

 암호 알고리즘의 핵심 큰 정수의 소인수 분해가 어렵다는 점을 이용하여 암호화를 시킨다.

이러한 RSA 암호 알고리즘은 전자상거래에서 가장 흔히 쓰고있는 공개키 알고리즘이다.

주로 적은 양의 데이터나 전자서명에 사용한다.또한 RSA 암호는 대칭키인 DES나 AES보다 속도가 느리므로 메시지 암호화에는 쓰이지 않고 주로 키를 암호화하는데 쓰인다.

 

RSA 암호 알고리즘 방식

1. A가 B에게 정보를 안전하게 보내고 싶어한다. 이때 RSA 알고리즘을 이용하고자 한다.

2. B가 공개키와 개인키를 만들어 A에게 공개키를 보낸다. (개인키는 B만 가지고 있다.)

3. A가 B로부터 받은 공개키를 이용하여 보낼 정보를 암호화한다.

4. A가 암호화된 정보를 B에게 보낸다.

5. B가 암호화된 정보를 받고 개인키를 이용하여 암호를 해독한다.

 

RSA 암호 알고리즘 원리

1. 개인키와 공개키 만들기

RSA 암호 알고리즘 첫 단계는 공개키와 개인키를 만드는 것이다.

공개키는 n,e라는 두 정수로 이루어져있고 개인키는 n,d라는 두 정수로 이루어져있다.

n 구하기

임의의 두 소수 p와 q를 정하고 n = p * q를 해주면 n을 구할 수 있다.

e 구하기

Φ(n) = (p - 1) * (q - 1)식을 이용하여 Φ(n)을 구한다.

e는 1 < e < Φ(n)로써 1과 Φ(n) 사이에 있고 Φ(n)와 서로소인 e를 정해주면 된다.

이러한 e는 공개키에 이용이 될 것이다.

서로소란 1 이외에 공약수를 가지지 않는 수를 의미한다.

d 구하기

(e * d) mod Φ(n) = 1

즉, e*d를 Φ(n)으로 나누었을 때 나머지가 1인 d를 구하면 된다. 이때 d는 개인키에 사용될 숫자이다.

이제 공개키에 이용될 (n, e)와 개인키에 이용될 (n, d)를 모두 구하였다. 즉, 개인키와 공개키가 생성되었다.

 

2. 암호화하기

STEP 1에서 구한 공개키를 이용해서 정보를 암호화 한다.

원래 정보를 M이라 하고 암호화된 정보를 C라 하자.

위의 식을 이용하여 M을 C로 암호화 하면 된다.

이때 암호화를 할 때 e와 n의 값을 알아야 하므로 공개키(n, e)가 있어야 암호화 할 수 있다는 것은 자명하다.

 

3. 복호화하기(해독하기)

이제 암호화되어 온 정보 C를 복호화(해독)할 순서이다.

페르마의 소정리에 의해 1번식이 성립하면 2번식도 성립하게 된다.

암호화 할때는 1번식을 사용했으므로 복호화 할때는 위의 식 즉, 2번식을 이용하여 복호화를 한다.

이때 암호화된 정보 C를 M으로 복호화(해독)할 때는 n과 d값을 알아야 한다.

이때 이 값을 아는 사람은 개인키(n, d)를 가진 사람 B 뿐이다.

반응형
,
반응형

블록 암호화에서의 운영 모드 및 패딩

암호화 할때, 운영 모드를 어떤 것을 할지 고민 일때 참고용.

ex> AES/CBC/PKCS7Padding

 

1. ECB (Electronic Code Block) Mode

- 가장 단순한 모드로 블록단위로 순차적으로 암호화 하는 구조이다.

- 한개의 블록만 해독되면 나머지 블록도 해독이 되는 단점이 있다. (Brute-Force Arttack, Dictionary Attack)

- 암호문이 블록의 배수가 되기 때문에 복호화 후 평문을 알기 위해서 Padding을 해야한다.

 

- error propagation : 각 블록이 독립적으로 동작하므로 한블록에서 에러가 난다고 해도 다른 블록에 영향을 주지 않는다. 해당 블록까지 에러 전파.

 

2. CBC(Cipher Block Chaining) Mode

- 블록 암호화 운영 모드 중 보안 성이 제일 높은 암호화 방법으로 가장 많이 사용된다.

- 평문의 각 블록은 XOR연산을 통해 이전 암호문과 연산되고 첫번째 암호문에 대해서는 IV(Initial Vector)가 암호문 대신 사용된다. 이 때, IV는 제 2의 키가 될수 있다.

- 암호문이 블록의 배수가 되기 때문에 복호화 후 평문을 얻기 위해서 Padding을 해야만 한다.

- 암호화가 병렬처리가 아닌 순차적으로 수행되어야 한다.

- error propagation : 깨진 암호문의 해당블록과 다음블록의 평문까지 영향을 미치게 됩니다. 두번째 복호화의 Ciphertext가 깨졌을 때 참조.

 

3. CFB(Cipher FeedBack) Mode

- 블록 암호화를 스트림 암호화처럼 구성 평문과 암호문의 길이가 같다(패딩이 필요 없다)

- 최초의 키생성 버퍼로 IV가 사용되며, 이때 IV는 제2의 키가 될수 있다.

- 스트림의 기본단위를 Bit단위로 설정할 수 있으며, Bit단위에 따라 CFB8~CFB128로 쓰인다.

- 암호화, 복호화 모두 암호화로만 처리할 수 있다.

- CBC모드와 마찬가지로 암호화는 순차적이고, 복호화는 병렬적으로 처리할 수 있다.

 

- error propagation : CBC모드와 마찬가지로 한 암호문블럭의 에러는 해당평문블록과 다음 평문블록, 이렇게 총 2개의 블록에 전파된다.

 

4. OFB(Output FeedBack) Mode

- 블록 암호화를 스트림 암호화처럼 구성해 평문과 암호문의 길이가 같다.(패딩이 필요없다)

- 암호화 함수는 키 생성에만 사용되며, 암호화 방법과 복호화 방법이 동일해 암호문을 한번 더 암호화하면 평문이 나온다. (복호화시에 암호화)

- 최초의 키생성 버퍼로 IV가 사용되며, 이 때 IV는 제2의 키가 될수 있다.

- 스트림의 기본 단위를 Bit단위로 설정할 수 있으며, Bit단위에 따라 OFB8~OFB128로 쓰인다.

 

- error propagation : 해당블록까지만~ 대응되는 한 블록에만 영향을 미치므로, 영상이나 음성과 같은 digitized analog신호에 많이 사용된다.

 

5. CTR (CounTeR) Mode

- 블록을 암호화할 때마다 1씩 증가해 가는 카운터를 암호화 해서 키스트림을 만든다. 즉 카운터를 암호화한 비트열과 평문블록과의 XOR를 취한 결과가 암호문 블록이 된다.

- CTR모드는 OFB와 같은 스트림 암호의 일종이다.

- CTR모드의 암복호화는 완전히 같은 구조가 되므로 구현이 간단하다.(OFB와 같은 스트림 암호의 특징)

- CTR모드에서는 블록의 순서를 임의로 암/복호화 할 수있다.(비표와 블록번호로부터 카운터를 구할 수 있기때문에)

- 블록을 임의의 순서로 처리 할 수 있다는 것은 처리를 병행 할 수 있다는 것을 의미한다.(병렬처리 가능)

- error propagation : 각 블록이 병렬처리 되므로 같은 블록내에서만 이루어짐.

 

- PKCS#5

암호 블록 사이즈가 8바이트에 맞춰져있다.

8바이트의 배수로 인풋을 맞춰줘야하는데 패딩에 들어가는 문자는 패딩할 갯수가 들어간다.

예시)

AA 07 07 07 07 07 07 07 : 1바이트 데이터 + 7바이트 패딩

AA BB 06 06 06 06 06 06 : 2바이트 데이터 + 6바이트 패딩

AA BB CC 05 05 05 05 05 : 3바이트 데이터 + 5바이트 패딩

주의 : 데이터가 8바이트인 경우에는 패딩이 필요 없어 보여도, 08을 8번 패딩한다.

 

AA A9 A8 A7 A6 A5 A4 A3 08 08 08 08 08 08 08 08 : 8바이트 데이터 + 8바이트 패딩

 

- PKCS#7

패딩할 숫자만큼 패딩 값을 채워넣어서 붙여주는 것은 PKCS#5와 동일.

따라서, 8바이트의 암호화 블럭 크기인 경우 PKCS#5 = PKCS#7이다.

하지만 현대의 암호화에서는 당연히 더 긴 암호화 블럭을 사용하기 때문에 달라진다.

AES256의 예를 들면, 256bit의 키를 사용하게 되고, 블럭 사이즈는 128bit이므로 32바이트의 키와 16바이트의 암호화 블럭을 사용하게 된다.

 

이 상황에서 PKCS#7은 패딩이 최대 16개까지 가능하다.

(8바이트인 경우 08을 패딩 8번 하듯이 10으로 패딩 16번을 수행한다.)

PKCS#7은 최대 가능한 패딩은 FF이므로, 255개가 된다.

 

두 개의 차이라 하면, PKCS#5는 8바이트 고정길이, PKCS#7은 1~255바이트의 가변길이이다.

반응형

'Tech develop > 인증' 카테고리의 다른 글

HMAC(Hash-based Message Authentication Code)  (1) 2021.07.29
RSA 암호 알고리즘이란?  (0) 2021.07.29
[Android] WhiteBox  (0) 2021.07.29
Android KeyStore 와 Keystore 의 차이  (0) 2021.07.29
,
반응형

Android 에서 사용하는 WhiteBox라고 불리는 것은 무엇이며, 어떻게 동작, 사용하는지 알아봅시다.

 

먼저 WhiteBox에 대해 알아보기 전에 암호키 탈취 공격 유형에는 어떠한 것들이 있는지 알면 좋습니다.

암호키 탈취 공격의 유형

먼저 암호키를 탈취하려는 공격 기법을 보면, 아래 3가지 기법으로 구분하고 있다

 

Black-box(블랙박스) 공격 : 암호문과 평문을 가지고, 비대칭알고리즘인 경우는 공개키(Public-key)를 가지고, 암호키(Secret-key 또는 Private-key)를 유추해 내는 공격이다. 즉 암호 알고리즘이 동작되는 내부 정보 및 과정을 볼 수 없기 때문에 Black-box란 용어를 사용한다. 보안 강도는 사용되는 "암호 알고리즘"과 "암호키 길이"에 따라 결정되어지는데, 이 경우는 높은 성능을 가진 컴퓨터를 사용하여 암호키를 유추해 내기 때문에 절대적인 시간이 필요하다. 물론 힌트가 되는 정보(오랜 시간 관찰하면 pattern을 알 수 있다고 함)를 입수하면, 계산 시간이 단축되지만 이러한 공격에 대비하는 방법은 주기적으로 암호키를 변경하는 것이다.

 

Gray-box(그레이박스) 공격 :암호 연산 시 발생되는 부가적인(Side) 정보 즉 소요 시간, 전력 사용 패턴, 발생되는 전자기파 정보 등을 입수하여 암호키를 유추하는 공격이다. 이러한 공격을 Side Channel(부채널) 공격이라고도 부르는데, 공격을 방지하기 위해서, 물리적으로 부가적인 정보가 유출되지 않도록 방지하는 기법과, 부가적인 정보가 유출되더라도 암호 알고리즘 상에서 암호키를 유추하지 못하도록 구현하는 기법을 사용한다. 암호 알고리즘 상에서 Side Channel 공격을 방지하는 기능을 구현한 알고리즘을 "Side Channel 내성 암호 알고리즘"이라고 부른다. 메모리를 얼려서 암호키를 알아내는 공격인, Cold Boot Attack 도 Side Channel 공격의 한 종류로 분류하고 있다. Gray-box란 Black-box 와 White-box 의 중간 단계에 속한다는 의미이다.

 

White-box(화이트박스) 공격 : White-box란 용어가 내포하듯이 암호 연산 과정을 들여다 보면서 공격을 한다는 의미이다. emulator 등의 software 분석 tool을 사용하여, 메모리 정보나 동작 과정 정보 등을 알아내어 암호키를 찾아낸다. 예를 들면, 암호키를 사용하는 특정 Application 이나 시스템을 입수하여, 자신의 분석 환경에서 디버깅 기법이나 리버스 엔지니어링(Reverse Engineering) 기법으로 암호 연산 과정을 추적하여 암호키를 찾아내는 방식이다. White-box 공격 과 Total-access 공격은 같은 의미가 된다.

 

Black-box 공격의 어려움(난이도)를 알기 때문에, 암호키 탈취를 목표로 하는 공격자는, Gray-box 공격이나 White-box 공격을 시도하는 것이다. White-box 공격을 하기 위해서는, 백도어 기능을 가진 악성코드(Malware)를 사용자 시스템에 몰래 설치하여 실행시키거나, 암호키 정보를 가지고 있는 디바이스를 훔치는 것 등의 방법을 사용한다.

 

White-box 공격을 방지하기 위한 Solution

White-box 공격을 방지하기 위한 대응 Solution으로 나온 것이 HSM(Hardware Solution) 과 WBC(White Box Cryptography)(Software Solution) 이다.

Application을 개발하는 입장에서 보면, 동작되는 시스템에서 HSM기능(TPM module 이나 TEE 지원 등) 지원 여부에 따라, 암호키 보관 기능을 구현해야 한다. HSM 기능이 없다면, password방식의 암호기능이나 난독화 기능을 사용하여, 암호키가 평문으로 노출되는 것을 방지해야 한다.

WBC(White Box Cryptography)는 Software 방식, 즉 암호키가 노출되지 않고 암호 함수 속에 들어가 동작되기 때문에, Application 개발자에겐, Hardware Independent한 매력적인 Solution으로 여겨지고 있다.

 

Hardware Solution : HSM

HSM(Hardware Security Module)은 단어가 의미하듯이 Hardware 적인 장치를 사용하여 암호키를 특별하고 안전한 장소에 보관하는기능을 가진 Module 이다. HSM의 모양은 구현 기능과 방식에 따라 다양한데, "IC Card(스마트카드)", "USB 디바이스", "PCI Card", "Network I/F를 가진 독립된 장비" 등 다양하다. 국내에선 HSM을 "보안 하드웨어"라고도 부른다.

 

HSM 기능이 내장되어 시장에 판매되고 있는 제품으론, TPM(Trusted Platform Module)을 장착한 노트북PC 와 TEE(Trusted Execution Environment) 나 SE(Secure Element)기능을 내장한 스마트폰이 있습니다(참고로, TEE는 안드로이드 OS 4.3버전부터 지원하고 있으며, 9.0버전부터는 SE 기능도 지원하고 있다. 안드로이드의 "Android KeyStore 와 Android Keystore"가 대표적이다).

보다 자세한 내용은 KeyStore 에서 다룰 예정으로 Skip하겠다.

 

Software Solution : White Box Cryptography

White Box Cryptography(화이트박스 암호)는 암호알고리즘이 동작되는 platform이 open-platform이라는 가정하에, 즉 누구나 접근할 수 있는 환경하에서, 암호기능(암호화 및 복호화)를 수행할 수 있도록 개발된 암호기술이다. 사용자 관점에서 본 open-platform이란, 공격자 입장에서 보면 White Box 공격을 할 수 있는 환경이 된다.

WBC(White Box Cryptography)가 구현이 되어 있으면, 사용자가 암호기능이 수행되는 디바이스를 분실했더라도, 또는 해커가 몰래 침투해 있더라도, 암호키가 유출되지 않는다는 것이다. 또한 HSM 사용시, 비용의 증가 및 구현(디바이스 내부에 HSM기능 구현)의 난이도가 있는 반면, WBC는 Software만으로 쉽게 구현되며, patch 또는 Upgrade도 쉽게 되는 장점이 있다.

요약하면, WBC는 White-box 공격이 있는 상황에서도 암호 정보(암호키 및 Salt 정보)를 안전하게 지키는 목적으로 개발된 암호 기술이다. 암호키가 외부 입력 값으로 들어가지 않고 암호 함수 속에 섞여 있는 이러한 상태를 obfuscation이라고 부른다.

 

WBC는 기존 표준화된 암호 알고리즘과 경쟁 상태에 있는 기술이 아니라, 표준화된 암호 알고리즘을 사용하면서 암호키가 노출되지 않도록 보완하는 기법이다. 즉 사용되는 암호키를 software적으로 보다 안전하게 보호하기 위하여 개발된 암호 기술이다.

WBC에 대한 기본적인 개념을 먼저 설명하면, 암호 함수 code 와 암호키를 무작위로 섞어서 혼잡된(obfuscated) 새로운 code를 generate(생성)하여 사용하는 기법이다. 제안되었을 당시는 Table들을 사용하여 mapping하는 방식을 사용하였으나, 그 후 table 없이 code만으로 동일한 보안 강도를 구현하는 방식도 개발되었다. 새롭게 생성된 code는 동일한 암복호화 기능을 수행하게 된다. 즉, 암호키가 노출되지 않는 상태로 암복호화 기능이 수행된다. 생성된 새로운 code는 "WB 암호 함수 code" 라고 부르고, 아래 그림은 기본적 개념을 표시한 것입니다.

 

처음에 나온 "original white-box AES" 의 내부 구현 방식은 key-dependent table들을 사용하여 mapping하는 것인데, 무작위(random) bijection 방식으로 인코딩된 Table들을 lookup(조회 또는 검색)하는 방식으로 AES를 구현하였으며, table들 안에 암호키 정보를 숨겨 두었다. 즉, Table 전체가 암호키 역할을 하는 것이다.

하지만 이 방식은 나오자마자 공격자들에 의해서 break되었다. 그래서 현재는 이 방법은 사용하지 않고 좀 더 해독하기 어려운 WBC solution이 나오기 시작했다. 상용화된 WBC solution은, WB Engine을 사용하여 암호키를 해독하기 어려운 size가 큰 "protected key"로 변환시키는 기법을 사용한다. 현재 판매되고 있는 WBC Solution에 대해서는 아직 break 되었다는 보고는 없다.

 

상용화되는 WBC의 개념

WBC가 제안되었을 당시는 암호키가 고정된 것으로 간주 했다. 즉 "protected key"가 WBC 암호 함수 속으로 들어갔습니다. 하지만 산업계에선 "protected key"를 변경할 수 있도록 즉 외부 입력 값으로 할 수 있기를 원하기 때문에, 암호키가 동적으로 변경되는 경우에 대한 WBC 구현 방식도 개발되었다.

WBC의 단점

- 동작되는 code 전체를 copy하면, 다른 디바이스에서 암호키를 몰래 암복호화 기능이 동작되므로, code가 주어진 device에서만 동작되도록 하는 기법(node-locking 기법)도 함께 적용되어져야 한다.

- 큰 size를 차지하는 Table 또는 protected key를 사용하기 때문에 많은 양의 메모리를 필요로 하고, 암복호화 속도가 상대적으로 느리다.

참고로, 암호키를 password 방식으로 암호화시켜 파일(file)로 저장하는 것은, HSM 방식도 아니고 WBC 방식도 아니다. 따라서 공격자는, 암호키 파일을 입수한 후에는, Black-box 공격으로 password를 알아내면 된다. Password를 알아내는 것은 암호키를 알아내는 것과 비교할 수 없이 난이도가 쉽다. Password를 알아내면 암호키를 사용할 수 있는 상태가 된다.

WBC의 개선점

- Size를 줄이고, 속도를 높이는 것.

반응형
,
반응형

Android KeyStore 와 Keystore 의 차이?

KeyStore 와 Keystore 는 한글로 읽으면 둘 다 '키스토어'이기 때문에, 동일한 단어로 들리지만, 실제로 다른 의미를 가지고 있다.

 

Android KeyStore Service

안드로이드 앱을 Google Play에 배포하기 위해서는 해당 앱을 서명하여 생성한 APK를 업로드하여 배포해야 하는데, 이 때, 서명에 사용되는 키 및 키저장소를 KeyStore라 한다.

해당 KeyStore는 AndroidStudio tool에서 생성 할 수 있으며, Google Play에 배포를 하게되면 같은 패키지로 업데이트를 진행 할 때, 반드시 최초에 APK를 서명했던 키스토어로 서명한 APK를 업로드 해야합니다.

만약, 최초에 서명한 키스토어를 잃어버렸다면 구글에게 메일을 보내 처리할 수는 있지만 까다롭기에 안잃어버리게 잘 관리하는 것이 중요!잃어버렸을 경우 : https://cfdf.tistory.com/30

 

Android OS 에서도, App 자체에서 사용하는 암호키를 보다 안전하게 보관하게 위한 서비스를 제공하고 있는 데, 이것이 바로 Android KeyStore Service(AndroidKeyStore 라고 부름)이다. KeyStore Service에서 제공하는 keystore(키스토어)에 암호키를 보관한다.

Android OS에서 암호화 기능을 제공하는 목적은 App 에서 다루고 있는 정보 중 외부로 유출이 되어서는 안되는 중요한 data를 안전하게 보관하는 방법은 암호화를 시켜 저장하는 방법 밖에 없기 때문. 특정 App에서 다루는 data는 다른 App에서는 access할 수 없으나, "Rooting"을 통하여 권한 상승을 하면, 모든 App에서 만든 data를 access할 수 있기 때문이다.

참고로, 사용 App 내부에 암호키를 hard coding된 상태로 저장하는 경우는 App을 디컴파일하면 암호키가 바로 노출이 된다.

 

Android Keystore

Android Device에서 암호키를 안전하게 저장하기 위해 사용하는 hardware 장치를 Android Keystore 라고 부른다. 즉 Android OS에서 제공하는 "KeyStore Service"를 제공하기 위해 만들어진 hardware가 바로 Android Keystore 이다. Android Device 제조사는 자신들의 Android Keystore를 hardware적으로 디자인하여, hardware를 구동하기 위한 driver software를 함께 제공하기만 하면 된다. 다시 정리하면, Android Keystore는 Android Device 제조사가 제공하는 "hardware 기반 secure key storage" 이다. Hardware란, TEE(Trusted Execution Environment) 또는 SE(Secure Element)를 지원하는 장치다.

GlobalPlatform(Secure chip 기술에 대한 사양을 만들고 발표하는 non-profit organization) 에서는 2010년도에 TEE에 대한 자신들의 표준을 발표했으며, TEE를 구현한 solution으로 ARM TrustZone 기술이 있다. TrustZone 기술을 기반으로 한 TEE 를 "TrustZone-based TEE" 라고 부른다. TEE는 main processor내에 있는 Secure Area 이며, Android OS 와는 독립된 별도의 OS로 동작함. Andorid 8 버전까지는 TEE 방식만 지원했다. 참고) iOS 도 Secure Enclave라 불리는 유사한 기능을 제공하고 있으며, Notebook PC에서도 암호키를 hardware적으로 안전하게 보관하기 위한 장치로 TPM(Trusted Platform Module) 를 장착하기도 한다. FIPS 140-2 인증을 받은 전용 HSM 장비 보다는 못하지만 software적인 방법 보다는 훨씬 안전하기 때문. 서버에서 사용하는 암호키는, "FIPS 140-2 Level 3 또는 Level 4 인증을 받은 전용 HSM 장비"를 사용하여 암호키를 안전하게 보관한다.

 

Android Keystore는 Android API 18버전(Jelly Bean, OS version 4.3)부터 지원하기 시작한 "hardware security" 기능이다. Android API에서는 Key 저장을 위하여 사용되는 "Key Storage"를 지원하기 위한 Interface로 java.security.KeyStore 라 불리는 class를 제공하고 있다.

Android Device는 부팅하면서, Keystore에 대한 driver가 없거나, hardware가 인식이 안되면, software적으로 Keystore기능을 구현한다. 따라서 좀 더 깊게 들어가면, Android Keystore는 "hardware 기반 AndroidKeyStore" 와 "software 기반 AndroidKeyStore" 두 가지 종류가 있는데 "software 기반 AndroidKeyStore" 는 "hardware 기반 AndroidKeyStore" 보다 덜 안전하다. 참고로, Android M(Version 6.0) 이전의 "software 기반 AndroidKeyStore" 는 rooting 된 기기에서 암호키 유출이 가능하다.

 

반응형

'Tech develop > 인증' 카테고리의 다른 글

HMAC(Hash-based Message Authentication Code)  (1) 2021.07.29
RSA 암호 알고리즘이란?  (0) 2021.07.29
블록 암호화에서의 운영 모드 및 패딩  (0) 2021.07.29
[Android] WhiteBox  (0) 2021.07.29
,
반응형

// // 기본적으로 현재날짜와 시간으로 설정된다.

//    Calendar today = Calendar.getInstance();    

//    System.out.println("이 해의 년도 : " + today.get(Calendar.YEAR));

//    System.out.println("월(0~11, 0:1월): " + today.get(Calendar.MONTH));

//    // (today.get(Calendar.MONTH) + 1)) 이런 형식으로 하면 다음월을 받아 올 수 

//    // 있다. today.get(Calendar.MONTH) + 1로 하면 이상한 값이 나온다. (괄호유무)

//    System.out.println("월(0~11, 0:1월): " + (today.get(Calendar.MONTH) + 1));

//    System.out.println("이 해의 몇 째 주: " + today.get(Calendar.WEEK_OF_YEAR));

//    System.out.println("이 달의 몇 째 주: " + today.get(Calendar.WEEK_OF_MONTH));

//    // DATE와 DAY_OF_MONTH는 같다.

//    System.out.println("이 달의 몇 일: " + today.get(Calendar.DATE));

//    System.out.println("이 달의 몇 일: " + today.get(Calendar.DAY_OF_MONTH));

//    System.out.println("이 해의 몇 일: " + today.get(Calendar.DAY_OF_YEAR));

//    // 1:일요일, 2:월요일, ... 7:토요일

//    System.out.println("요일(1~7, 1:일요일): " + today.get(Calendar.DAY_OF_WEEK)); 

//    System.out.println("이 달의 몇 째 요일: " + today.get(Calendar.DAY_OF_WEEK_IN_MONTH));

//    System.out.println("오전_오후(0:오전, 1:오후): " + today.get(Calendar.AM_PM));

//    System.out.println("시간(0~11): " + today.get(Calendar.HOUR));

//    System.out.println("시간(0~23): " + today.get(Calendar.HOUR_OF_DAY));

//    System.out.println("분(0~59): " + today.get(Calendar.MINUTE));

//    System.out.println("초(0~59): " + today.get(Calendar.SECOND));

//    System.out.println("1000분의 1초(0~999): " + today.get(Calendar.MILLISECOND));

//    // 천분의 1초를 시간으로 표시하기 위해 3600000으로 나누었다.(1시간 = 60 * 60초)

//    System.out.println("TimeZone(-12~+12): " + 

//    (today.get(Calendar.ZONE_OFFSET)/(60*60*1000))); 

//    // 이 달의 마지막 일을 찾는다.

//    System.out.println("이 달의 마지막 날: " + today.getActualMaximum(Calendar.DATE) );





(1) YYYYMMDD 문자 Calendar 로 넘겨주기


String select_Date = "20150101";

Calendar month = Calendar.getInstance();

SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");

month.setTime(formatter.parse( select_Date ));





(2) Calendar 날짜 String 으로 뽑아주기


String date = ""+new SimpleDateFormat("yyyyMMdd").format(calendarData.getTime());


or


String selectDate = "" + android.text.format.DateFormat.format("yyyyMMdd", calendarData);


출처 : https://m.blog.naver.com/PostView.nhn?blogId=komgurrbs&logNo=220262403979&proxyReferer=https:%2F%2Fwww.google.com%2F

반응형
,
반응형

문제 발생

Enum

@AllArgsConstructor
@Getter
public enum Foo {

  A("에이", "a"),
  B("비", "b"),
  C("씨", "c");

  private String korean;
  private String small;

}

 

Controller

@RestController
public class EnumController {

  @GetMapping("/enum/{code}")
  private RestResponse showFoo(@PathVariable String code){
    return new RestResponse(true, Foo.valueOf(code));
  }
}

 

Response 객체

@Getter
public class RestResponse {

  private boolean success;

  private Foo data;

  public RestResponse(boolean success, Foo data) {
    this.success = success;
    this.data = data;
  }
}

위와 같이 코드 값을 주소에 입력받으면,

코드에 해당하는 전체 객체를 리턴해주고 싶은데, 아래와 같이 출력됐다.

해결 방법

1. Enum 객체 전체 리턴해주기

@JsonFormat(shape = Shape.OBJECT) // 추가
@AllArgsConstructor
@Getter
public enum Foo {

  A("에이", "a"),
  B("비", "b"),
  C("씨", "c");

  private String korean;
  private String small;

}

Enum 객체에 @JsonFormat 어노테이션을 추가해준다.

리턴받는 기댓값은 객체 형태이기 때문에 Shape.OBJECT로 설정해준다.

 

2. 값만 리턴해주기

@AllArgsConstructor
@Getter
public enum Foo {

  A("에이", "a"),
  B("비", "b"),
  C("씨", "c");

  @JsonValue // 추가
  private String korean;
  private String small;

}

만약 특정 값만 리턴하고 싶다면, 변수에 @JsonValue 어노테이션을 추가해준다.

상황에 따라 골라서 쓰면 될 것 같다. 😁


출처 : https://shinsunyoung.tistory.com/73

반응형
,
반응형

1. 개요

  • 라이브러리가 OpenAPI 3.0 스펙에 맞는 JSON을 자동으로 만들어 주면, Swagger UI는 만들어진 JSON을 바탕으로 화면에 표시 해줍니다.
  • Spring Boot 2.0.9.RELEASE로 테스트 하였습니다.

2. 문제 해결

  • messageconverter가 설정되어 있어서 Swagger UI가 /v3/api-docs/ end-point로 접근시 String으로 감싼 JSON 형으로 리턴됨.
    1. HttpServletRequest 객체의 getRequestURI 메소드를 사용하여 요청한 Uri를 가져옴.
    2. Uri가 /v3/api-docs/ 또는 /v3/api-docs/swagger-config 인지 확인하여 원본 내용을 리턴하게 예외처리. (e.g. json이면 json으로)

3. build.gradle 파일에 dependency 추가

dependencies {
    implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.2.30'
}

4. 설정 파일에 관련 설정 추가

springdoc:
  api-docs:
    groups:
      enabled: true
  swagger-ui:
    path: /swagger-ui.html
    displayRequestDuration: true
    groups-order: DESC

5. OpenApiConfig.java 파일 작성

package kr.webgori.lolien.discord.bot.config;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Contact;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.info.License;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@OpenAPIDefinition(
    info = @Info(title = "lolien-discord-bot API 명세서",
        description = "API 명세서",
        version = "v1",
        contact = @Contact(name = "webgori", email = "webgori@gmail.com"),
        license = @License(name = "Apache 2.0",
            url = "http://www.apache.org/licenses/LICENSE-2.0.html")
    )
)
@Configuration
public class OpenApiConfig {
  /**
   * customGameOpenApi.
   * @return GroupedOpenApi
   */
  @Bean
  public GroupedOpenApi customGameOpenApi() {
    String[] paths = {"/custom-game/**"};
    return GroupedOpenApi.builder().setGroup("내전 관련 API").pathsToMatch(paths)
        .build();
  }

  /**
   * leagueOpenApi.
   * @return GroupedOpenApi
   */
  @Bean
  public GroupedOpenApi leagueOpenApi() {
    String[] paths = {"/league/**"};
    return GroupedOpenApi.builder().setGroup("리그 관련 API").pathsToMatch(paths)
        .build();
  }
}

6. Swagger UI 확인

  • http://IP 또는 도메인:포트/swagger-ui.html 으로 접속 후 확인


출처 : https://webgori.github.io/spring/2020/02/09/OpenAPI-3.0%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-Spring-REST-API-%EB%AC%B8%EC%84%9C%ED%99%94.html

반응형
,
반응형

이번 포스트에서는 스크롤뷰(ScrollView)의 자동 스크롤 방법에 대해 알아 보도록 하겠습니다.


맨 위 / 아래로 ScrollView 자동 스크롤

ScrollView 의 맨 위/아래로 자동 스크롤 하는 방법은 fullScroll을 사용하는 방법입니다.

인자값으로는 ScrollView.FOCUS_DOWN 과 ScrollView.FOCUS_UP 이 있습니다.

final ScrollView scrollview = ((ScrollView) findViewById(R.id.scrollview));
scrollview.post(new Runnable() {
    @Override
    public void run() {
        scrollview.fullScroll(ScrollView.FOCUS_DOWN);
    }
});



ScrollView 자동 스크롤 - 기본 함수 사용

특정 위치만큼만 스크롤 하려면 아래와 같이 smoothScrollBy() 혹은 smoothScrollTo() 함수를 이용하면 됩니다.

final ScrollView scrollview = ((ScrollView) findViewById(R.id.scrollview));
scrollview.post(new Runnable() {
    @Override
    public void run() {
        scrollview.smoothScrollBy(0, 800);
    }
});



ScrollView 자동 스크롤 - 스크롤 속도 변경

위에 소개된 함수들은 스크롤 속도가 정해져 있어 속도를 느리게 하고 싶으신 분들은 아래와 같은 방법으로 스크롤 속도를 조절할 수 있습니다.

* scrollTo 는 스크롤 하고 싶은 곳의 Y 값, 만약 맨 안래로 하고 싶으면 scrollView.getBottom() 을 넣어주면 됨.

final ScrollView scrollview = ((ScrollView) findViewById(R.id.scrollview));
scrollview.post(new Runnable() {
    @Override
    public void run() {
        ObjectAnimator.ofInt(scrollView, "scrollY",  scrollTo).setDuration(duration).start();
    }
});




출처: https://tiann.tistory.com/13 [티앤의 IT월드]

반응형
,
반응형

add 와 replace 중요성의 차이점은 replace 가 기존의 조각을 제거하고 새로운 조각을 추가하는 것입니다. 즉, 다시 버튼을 누르면 대체 된 프래그먼트가 호출되고 onCreateView가 호출됩니다. add 는 기존의 조각을 유지하고 기존의 조각이 활성화 될 것이라는 의미의 새 조각을 추가하는 반면 '뒤로'단추를 누르면 onCreateView가 기존 조각 (새 조각 전에 있던 단편 조각이 추가됨). 프래그먼트의 라이프 사이클 이벤트 onPause와 관련하여, onResume, onCreateView 및 기타 라이프 사이클 이벤트는 replace 될 경우 호출되지만 add 경우에는 호출되지 않습니다.



add()
 와 replace() 기본적인 차이점은 다음과 같이 설명 할 수 있습니다.

  • add() 는 일부 루트 요소에 단편을 단순히 추가하는 데 사용됩니다.
  • replace() 비슷하게 동작하지만 이전에는 이전 조각을 제거한 후 다음 조각을 추가합니다.

addToBackStack() 을 add() 또는 replace() 와 함께 사용하면 정확한 차이를 확인할 수 있습니다.

add() ... onCreateView가 호출되지 않았을 때 back button을 누르면, replace() 경우에는 back 버튼을 누르면 ... oncreateView가 매번 호출됩니다.


출처 : https://code.i-harness.com/ko/q/11c55df

반응형
,