JWE, jWK

허진수·2023년 1월 22일
0


JOSE Header

  • enc - content encryption알고리즘 정의, 대칭 AEAD(Authenticated Encryption with Associated Data) 알고리즘이어야 함.
  • alg - CEK(Content Encryption Key)를 암호화하는 알고리즘 정의, 키 랩핑 알고리즘

JWE Encrypted Key

  • 토큰 발행 시에 enc에 맞는 랜덤한 key를 생성하고 이를 alg의 알고리즘을 써서 암호화 진행
  • 암호화된 키가 들어감.

JWE Initialization Vector(IV)

  • 일부 초기화 벡터가 필요한 알고리즘을 위한 공란
  • 항상 같은 결과가 나오는 것을 방지하기 위해 추가됨.
  • AES-GCM알고리즘에서 사용

JWE Ciphertext

  • CEK와 enc알고리즘으로(IV, AAD 사용) payload를 암호화한 값

JWE Authentication Tag

  • ciphertext와 함께 생성됨
  • 무결정 증명시 사용

JWE AAD

  • 암호화된 payload와 함께 무결성을 증명하는데 사용

서명 과정(JWE Compact Serialization)

  1. CEK를 만들 알고리즘 파악
  2. CEK생성 및 Encrypted Key 계산, 이때 alg 및 JWK 사용
  3. Encrypted Key를 base64-url로 인코딩
  4. 임의의 Initialization Vector값 생성 및 base64-url 인코딩
  5. header를 UTF-8인코딩&base64url 인코딩 하여 Jose Header 생성
  6. Jose Header의 ASCII 값을 계산하여 AAD 생성
  7. CEK, IV, AAD를 이용해 payload 암호화
  8. AEAD를 사용해 CiphertextAuthentication Tag 생성
  9. Cipertext를 base64-url 인코딩하여 JWE Cipertext 생성
  10. Authentication Tag 를 base64-url 인코딩 하여 JWE Authenticate Tag생성

AES-GCM

AES(Advanced Encryption Standard)

  • 암호화와 복호화 과정에서 동일한 키를 사용하는 대칭키 알고리즘
  • 2001년 미국 표준 기술 연구소(NIST)에 의해 제정된 암호화 방식
  • AES 표준은 여러 Rijindael 알고리즘 중 블록 크기가 128비트인 알고리즘
  1. ECB(Electronic Code Block)
    1. 기본 타입, 역추적 가능, 암호화 키 유추 가능
  2. CBC(Ciper Block Chaining)
    1. ECB 보완
    2. 암호화 키에 Initial Vector 추가
    3. 병렬처리 불가
  3. GCM(Galois/Counter Mode)
    1. CBC 보완
    2. 데이터의 hash가 암호문에 포함 -> 복호화시 변조 확인 가능
    3. 병렬 처리 가능

RSA-OAEP

OAEP(Optimal Asymmetric Encryption padding)

  • RSA는 동일한 키 값을 사용하므로 중간에 암호문을 도청하더라도 해독이 어렵지만 동일한 문자가 사용되었음은 알아챌 수 있다.-> 같은 문자라도 다른 결과가 나오도록 padding을 추가한 것

PKCS

  • PKCS는 Public-Key Cryptography Standard로 RSA 시큐리티에서 정한, 공개 키 암호에 대한 사용 방식에 대한 표준 프로토콜
  • 공개 키 기반구조, PKI(Public Key Infrastructure)를 기반으로 한 1990년대 초에 RSA Security LLC에서 고안 및 게시판 공개 키 암호화 표준 그룹

JWK(Json Web Key)

  • JWK는 암호화 키를 표현하기 위한 다양한 정보를 담은 JSON 객체에 관한 표준이다.
  • RFC7517
  • 암호화 키를 나타내는(Cryptographic Key) JavaScript Object Notation(JSON) 데이터 구조
  • JWKs(JWK의 집합) 도 표현
  • key
    • kty: key type(RSA EC…)
    • key_ops: key option(sign, enc)
  • rsa key 구성
    • e: rsa exponent(public key에 존재)
    • n: rsa modoulus(public key에 존재)
    • d: D
    • p: P
    • q: Q
    • dp: exponent1
    • dq: exponent2
    • qi: coefficient

Python-jose 에서 JWE/JWK 사용 With RSA

from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
from jwt.utils import to_base64url_uint


pri_format = serialization.load_pem_private_key(private_key.encode(), password=None, backend=default_backend())
pub_format = serialization.load_pem_public_key(public_key.encode(), backend=None)
breakpoint()
# pub
key = {
    "kty": "RSA",
    "use": "enc",
    "alg": "RSA-OAEP-256",
    'e': to_base64url_uint(pub_format.public_numbers().e).decode(),
    'n': to_base64url_uint(pub_format.public_numbers().n).decode()
}
# pri
key2 = {
    "kty": "RSA",
    "key_ops": ["enc"],
    'd': to_base64url_uint(pri_format.private_numbers().d).decode(),
    'p': to_base64url_uint(pri_format.private_numbers().p).decode(),
    'q': to_base64url_uint(pri_format.private_numbers().q),
    'e': to_base64url_uint(pri_format.public_key().public_numbers().e).decode(),
    'n': to_base64url_uint(pri_format.public_key().public_numbers().n).decode(),
    'dp': to_base64url_uint(pri_format.private_numbers().dmp1).decode(),
    'dq': to_base64url_uint(pri_format.private_numbers().dmq1).decode(),
    'qi': to_base64url_uint(pri_format.private_numbers().iqmp).decode()
}

# key = jwk.construct(key) JWK 사용
res = jwe.encrypt(plaintext='string'.encode('utf-8-sig'), key=key, algorithm='RSA-OAEP-256', encryption='A128GCM')

res1 = jwe.decrypt(res, key2)

참고 자료

profile
안녕하세요

0개의 댓글