Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions 008. KeyStore System and Security/Part 0 - Keyword List.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
## Keystore System & Security

## Security Basic

* Encrypt/Decrypt (암호화 / 복호화)
* Encrypt: 암호화에서, 암호화는 정보를 인코등하는 프로세스이다. 일반 텍스트로 알려진 정보의 원래 표현을 암호문으로 알려진 대체 형식으로 변환한다. 이상적으로는 승인된 사람만이 암호문을 다시 평문으로 해독가능하며 원본 정보에 접근 가능하다. 그 자체로 간섭을 방지하는 것이 아니라 잠재적인 인터셉터가 이해할 수 있는 콘텐츠 자체를 거부한다.
* Decrypt: 암호화된 데이터를 사람이 읽고 이해할 수 있는 형태로 변환하는 프로세스이다. 텍스트를 수동으로 암호화를 해체하거나 원본 데이터를 암호화하는데 사용되는 키를 사용하여 복호화를 수행한다.

* Symmetric Key (대칭키)
대칭 키 암호에서는 암호화를 하는 측과 복호화를 하는 측이 같은 암호 키를 공유한다. 대부분의 대칭 키 암호는 공개 키 암호와 비교하여 계산 속도가 빠르다. 대칭 키 암호는 암호화하는 단위에 따라 Block Cipher 와 Stream Cipher 가 있다.

* DES: 암호화 및 복호화 키가 동일하고 비대칭에 비해 속도가 빠르다.
* AES: DES를 대체한 암호 알고리즘이며 암호화와 복호화 과정에서 동일한 키를 사용한다.

* Block Cipher: 한번에 텍스트를 블록 단위로 가져와서 암호화한다. 64 bit 또는 64 bit이상을 사용한다. 암호화의 복잡성은 간단하다. 복호화하는 과정이 어렵다. 스트림 방식보다 느리다.
* Stream Cipher: 한번에 텍스트를 1바이트 단위로 가져와서 암호화한다. 8 bit 를 사용한다. 암호화의 복잡성은 복잡하다. 복호화하는 과정이 쉽다. 블락 방식보다 빠르다.

* Hash
프로그램이나 파일이 원본 그대로인지를 확인하는 무결성 검사 등에 사용된다.
* MD5: 임의의 길이의 메시지(variable-length message)를 입력받아, 128비트짜리 고정 길이의 출력값을 낸다. 암호화 결함이 발견되어 보안 용도로 사용할 때에는 SHA와 같은 다른 알고리즘을 사용하는 것이 권장된다.
* sha-256: SHA(Secure Hash Algorithm) 알고리즘의 한 종류로서 어떤 길이의 값을 입력하더라도 256 bit 의 고정된 결과값을 반환한다. 단방향 암호화 방식이기 때문에 복호화가 불가능하다. 복호화를 하지 않아도 되기 때문에 속도가 빠르며, 비밀번호를 확인하는 용도등으로 사용 가능하다.

* Checksum
우발적인 변경을 방지하기 위한것이다. 1 byte 가 변경되면 체크섬이 변경된다. 체크섬은 악의적인 변경으로부터 보호하기에는 안전하지 않다. 특정 체크섬으로 파일을 만드는 것은 매우 쉽다.

* MAC : Message Authentication Code
MAC(메시지 인증코드) 또는 태그는 컴퓨터 사용자가 계정이나 포털에 액세스하기 위해 입력하는 보안 코드이다. 이 코드는 사용자가 보낸 메시지 또는 요청에 첨부된다. MAC 은 사용자 액세스 권한을 부여하기 위해 수신된 시스템에서 인식할 수 있어야 한다.
* HMAC(Hash-based MAC): 송신자, 수신자 공유된 비밀키를 가지면 송신자가 키와 메시지를 해시를 생성해서 메시지와 해시를 전송하면 수신자는 수신된 해시와 수신 받은 메시지를 통해 생성한 해시를 비교한다.
* CMAC(Cipher-based MAC): 누군가가 중간에서 메시지와 MAC을 가로채서, 메시지를 변조시키고, MAC도 다시 새롭게 만들어서 보낼 수 있다. 이런 경우에 수신자는 메시지의 MAC과 받은 MAC이 일치하므로 메시지가 변조된지 알 길이 없다. 이러한 단점을 보안한 것이 CMAC 이며, 메시지 암호화 과정에서 나온 결과물을 MAC으로 사용한다.

* Asymmetric Key (비대칭키)
비대칭암호화는 두 개의 별개의 관련 키를 사용한다. 하나의 키인 공개 키는 암호화에 사용되고 다른 하나인 개인 키는 복호화에 사용한다. 이름에서 알 수 있듯이 개인키는 인증된 수신자만 메시지를 해독할 수 있도록 비공개로 되어있다.
* Diffie-Hallman: 상대방의 공개키와 나의 개인키를 이용하여 계산을 하면 비밀키가 나온다. 이 비밀키를 사용해서 데이터를 암호화해서 보내고 복호화해서 해석한다.
* RSA: 공개키 암호 알고리즘의 하나로서 세계적으로 사실상의 표준이다. 인수분해 문제 해결의 높은 난이도를 이용해 암호화뿐만 아니라 전자 서명의 용도로도 사용된다. 모두에개 공개하는 공개키(Public key)와 공개해서는 안되는 개인키(Private Key) 로 구성된다. 공개키는 메시지를 암호화할때 사용하고, 개인키는 암호화된 메시지를 복호화할때 사용한다.
* ECC: 암호키 길이가 길어지면 보안 강도는 높아지지만 속도가 느려집니다. 하지만, ECC(Elliptic Curve Cryptography) 를 사용하면 짧은 키로도 동일한 암호 성능을 가지는데, 이는 컴퓨터 성능이 낮아도 암호 성능을 유지할 수 있다. 이러한 이유로 RSA를 대체할 차세대 공개키 암호기술로 부상하고 있다.







https://en.wikipedia.org/wiki/Encryption

[https://ko.wikipedia.org/wiki/%EB%8C%80%EC%B9%AD_%ED%82%A4_%EC%95%94%ED%98%B8](https://ko.wikipedia.org/wiki/대칭_키_암호)

https://www.geeksforgeeks.org/difference-between-block-cipher-and-stream-cipher/

https://newbedev.com/checksum-vs-hash-differences-and-similarities

https://findanyanswer.com/what-is-checksum-byte

https://stackoverflow.com/questions/460576/hash-code-and-checksum-whats-the-difference

https://bamdule.tistory.com/233

https://ddongwon.tistory.com/38

https://cheapsslsecurity.com/blog/what-is-asymmetric-encryption-understand-with-simple-examples/

https://www.crocus.co.kr/1233

[https://yjshin.tistory.com/entry/%EC%95%94%ED%98%B8%ED%95%99-%EB%8C%80%EC%B9%AD%ED%82%A4-%EC%95%94%ED%98%B8-DESData-Encryption-Standard](https://yjshin.tistory.com/entry/암호학-대칭키-암호-DESData-Encryption-Standard)

https://www.crocus.co.kr/1230

[https://yjshin.tistory.com/entry/%EC%95%94%ED%98%B8%ED%95%99-%EB%B9%84%EB%8C%80%EC%B9%AD%ED%82%A4-%EC%95%94%ED%98%B8-RSA-%EC%95%94%ED%98%B8%EC%8B%9C%EC%8A%A4%ED%85%9C](https://yjshin.tistory.com/entry/암호학-비대칭키-암호-RSA-암호시스템)

https://medium.com/humanscape-tech/blockchain-elliptic-curve-cryptography-ecc-49e6d7d9a50a

https://developer-mac.tistory.com/83
155 changes: 155 additions & 0 deletions 008. KeyStore System and Security/Part 1 - What is KeyStore System?.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
## Android Keystore

Android Keystore 시스템을 사용하면 암호화 키를 컨테이너에 저장하여 기기에서 키를 추출하기 어렵게 할 수 있다. 키 저장소에 키가 저장되면, 키 자료는 내보낼 수 없는 상태로 유지하면서 키를 암호화 작업에 사용할 수 있다. 이 시스템에서는 키 사용 시기와 사용 방법을 제한하는 기능도 제공한다. 예를 들어 키 사용을 위해 사용자 인증을 요구하거나, 특정 암호화 모드에서만 키를 사용하도록 제한할 수 있다. Keystore 시스템은 Android 4.0(API 수준 14)에서 도입된 KeyChain API에서 사용한다. Android 4.3(API 수준 18)에서 도입된 Android Keystore 제공자 기능 및 Jetpack의 일부로 제공되는 보안 라이브러리에서도 사용한다.

### 보안기능

* 추출차단: Android Keystore는 애플리케이션 프로세스와 Android 기기 전체에서 키 자료의 추출을 차단하여 Android 기기 외부에서 키 자료의 무단 사용을 줄인다.

* 키 사용 승인: Android Keystore는 앱에서 승인된 키 사용처를 지정하도록 하여 앱 프로세스 외부에 적용하는 방식으로 Android 기기에서 키 자료의 무단 사용을 줄인다.

### 키체인 또는 Android Keystore provider

시스템 수준의 사용자 인증 정보를 원하는 경우 KeyChain API를 사용한다. 앱에서 KeyChain API를 통해 사용자 인증 정보 사용을 요청하는 경우 사용자는 설치된 사용자 인증 정보 중 앱이 액세스할 수 있는 사용자 인증 정보를 시스템 제공 UI를 통해 선택한다. 이렇게 하면 사용자 동의를 받아 여러 앱이 동일한 사용자 인증 정보 집합을 사용할 수 있다.
개별 앱이 전용으로 액세스할 수 있는 고유한 사용자 인증 정보를 저장할 수 있게 하려면 Android Keystore 제공자를 사용한다. Android Keystore 제공자를 통해 앱에서 전용으로 사용할 수 있는 사용자 인증 정보를 관리할 수 있을 뿐만 아니라 KeyChain API가 시스템 수준의 사용자 인증 정보에 제공하는 것과 동일한 보안 이점을 얻을 수 있다. 이 방법은 사용자 인증 정보를 선택하기 위한 사용자 상호작용이 필요 없다.

* Dependency 를 추가
security-crypto 1.1.0-alpha01 이상부터 사용할 수 있다.

implementation "androidx.security:security-crypto:1.1.0-alpha03"

* 새 비공개 키 생성
새 PrivateKey를 생성하려면 자체 서명 인증서에 포함될 초기 X.509 속성도 지정해야 한다.

val mainKey = MasterKey.Builder(applicationContext)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()

// KeyPairGenerator 는 MinSDK 23+
val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_EC,
"AndroidKeyStore"
)
val parameterSpec: KeyGenParameterSpec = KeyGenParameterSpec.Builder(
"keystoreAlias",
KeyProperties.PURPOSE_SIGN // or KeyProperties.PURPOSE_VERIFY
).run {
setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
build()
}

kpg.initialize(parameterSpec)

val kp = kpg.generateKeyPair()

* 안전하게 암호화된 키 가져오기
Android 9(API 수준 28) 이상에서는 ASN.1로 인코딩된 키 형식을 사용하여 암호화된 키를 Keystore로 안전하게 가져올 수 있다.

KeyDescription ::= SEQUENCE {
keyFormat INTEGER,
authorizationList AuthorizationList
}

SecureKeyWrapper ::= SEQUENCE {
wrapperFormatVersion INTEGER,
encryptedTransportKey OCTET_STRING,
initializationVector OCTET_STRING,
keyDescription KeyDescription,
secureKey OCTET_STRING,
tag OCTET_STRING
}

* 키 저장소 항목 작업

val ks: KeyStore = KeyStore.getInstance("AndroidKeyStore").apply {
load(null)
}
val aliases: Enumeration<String> = ks.aliases()

* 데이터 서명 및 확인

// 데이터 서명
val alias = "AndroidDeepDive"
var privateKey : PrivateKey? = null

val ks: KeyStore = KeyStore.getInstance("AndroidKeyStore").*apply *{**
**load(null)
}**

**if (ks.containsAlias(alias)) {
Log.d("AndroidDeepDive", "Alias exist already")
val entry: KeyStore.Entry = ks.getEntry(alias, null)
if (entry is KeyStore.PrivateKeyEntry) {
privateKey = entry.*privateKey
*}
}
else {
Log.d("AndroidDeepDive", "Alias not exist")
val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(
KeyProperties.*KEY_ALGORITHM_EC*,
"AndroidKeyStore"
)

val parameterSpec: KeyGenParameterSpec = KeyGenParameterSpec.Builder(
alias,
KeyProperties.*PURPOSE_SIGN *// or KeyProperties.PURPOSE_VERIFY
// KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
).*run *{
setDigests(
KeyProperties.*DIGEST_SHA256*,
KeyProperties.*DIGEST_SHA512
*)
build()
}**

**kpg.initialize(parameterSpec)

val kp = kpg.generateKeyPair()
privateKey = kp.*private
*}

val data = "blahblah".*toByteArray*(Charset.defaultCharset())
val signature: ByteArray = Signature.getInstance("SHA256withECDSA").*run ***{
**initSign(privateKey)
update(data)
sign()
**}**

// 데이터 확인
val entry = ks.getEntry(alias, null) as? KeyStore.PrivateKeyEntry
if (entry != null) {
val valid: Boolean = Signature.getInstance("SHA256withECDSA").*run *{**
**initVerify(entry.*certificate*)
update(data2)
verify(signature)
}**

**Log.d("AndroidDeepDive", "signature: $valid")
}
else {
Log.w("AndroidDeepDive", "Not an instance of a PrivateKeyEntry")
}



## Trusted Execution Environment(TEE)

TEE 는 메인 프로세세의 보안 영역이다. 내부에 로드된 코드와 데이터가 기밀성과 무결성과 관련하여 보호되도록 보장한다. 격리된 실행 환경인 TEE 는 격리된 실행, TEE 로실행되는 어플리케이션의 무결성과 같은 보안 기능을 제공한다. 일반적으로 TEE 는 rich OS 보다 디바이스에서 실행되는 신뢰할 수 있는 응용프로그램에 대해 더 높은 수준의 보안을 제공하고 SE(secure element) 보다 더 많은 기능을 제공하는 실행 공간을 제공한다.

A **trusted execution environment** (**TEE**) is a secure area of a [main processor](https://en.wikipedia.org/wiki/Central_processing_unit). It guarantees code and data loaded inside to be protected with respect to confidentiality and integrity[[*clarification needed](https://en.wikipedia.org/wiki/Wikipedia:Please_clarify)*].[[1]](https://en.wikipedia.org/wiki/Trusted_execution_environment#cite_note-oulpita.com-1) A TEE as an isolated execution environment provides security features such as isolated execution, integrity of applications executing with the TEE, along with confidentiality of their assets.[[2]](https://en.wikipedia.org/wiki/Trusted_execution_environment#cite_note-2) In general terms, the TEE offers an execution space that provides a higher level of security for trusted applications running on the device than a rich operating system (OS) and more functionality than a ‘secure element’ (SE).

TEE(신뢰할 수 있는 실행 환경)는 주 프로세서의 보안 영역입니다. 내부에 로드된 코드와 데이터가 기밀성과 무결성과 관련하여 보호되도록 보장합니다[설명 필요].[1] 격리된 실행 환경인 TEE는 자산의 기밀성과 함께 격리된 실행, TEE로 실행되는 애플리케이션의 무결성과 같은 보안 기능을 제공합니다.[2] 일반적으로 TEE는 풍부한 운영 체제(OS)보다 장치에서 실행되는 신뢰할 수 있는 응용 프로그램에 대해 더 높은 수준의 보안을 제공하고 ‘보안 요소’(SE)보다 더 많은 기능을 제공하는 실행 공간을 제공합니다.





https://developer.android.com/training/articles/keystore?hl=ko

https://source.android.com/security/keystore?hl=ko

https://en.wikipedia.org/wiki/Trusted_execution_environment

https://linsoo.pe.kr/archives/28119

https://linsoo.pe.kr/archives/28144
Loading