Hash

  • Cryptography hash('digest’라고도 함)는 텍스트 또는 데이터 파일에 대한 일종의 'signature'.

SHA, Secure Hash Algorithm

SHA-256

val hash1 = MessageDigest
    .getInstance("SHA-256")
    .digest(origin.toByteArray())
    .fold("", { str, it -> str + "%02x".format(it) })

// required "org.bouncycastle:bcprov-jdk15on"
val hash2 = MessageDigest
    .getInstance("SHA-256")
    .digest(origin.toByteArray())
    .let { String(Hex.encode(it)) }

val hash3 = MessageDigest
    .getInstance("SHA-256")
    .digest(origin.toByteArray())
    .let { BigInteger(1, it).toString(16).padStart(32, '0') }

MD5, Message-Digest algorithm 5

  • 암호화 해시 함수

  • RFC 1321

crpyto

AES, Advanced Encryption Standard

  • 대칭키를 쓰는 블럭 암호

AES 256

  • 256 암호화 키 사용

  • aes-256-cbc로 생성하면 64byte 키값이 생성됨

    salt=5B1CD0A0E6F91535
    key=1F3CDAD3FDD397162A8431B24D67B65C7C4A0277BC07223C19B7CD711F4376F5
    iv =BF9B3C014A9061CB7F33FF3451023ABE
  • 블록암호화를 진행하기 위해 패딩 기법 필요

  • 데이터를 특정크기로 맞추기 위해 채워넣는 방법

    val c = Cipher.getInstance("AES/CBC/PKCS5Padding")
  • JDK에서는 지원하지 않음

    1. JCE 설치

    2. 외부 디펜던시 추가

      build.gradle.kts
      dependencies {
          api("org.bouncycastle:bcprov-jdk15on:1.66")
      }
      AesUtils.kt
      object AesUtils {
          init {
              Security.addProvider(BouncyCastleProvider())
          }
      
          fun encrypt256(data: String, hexAesKey: String): ByteArray {
              val keySpec = SecretKeySpec(hexAesKey.hexStringToByteArray(), "AES")
              val ivSpec = IvParameterSpec(ByteArray(16) { 0x00 })
      
              return Cipher
                  .getInstance("AES/CBC/PKCS7Padding", BouncyCastleProvider.PROVIDER_NAME)
                  .apply { init(Cipher.ENCRYPT_MODE, keySpec, ivSpec) }
                  .doFinal(data.toByteArray(StandardCharsets.UTF_8))
          }
      }
PKCS#7 Padding
  • http://tools.ietf.org/html/rfc2315

  • 블럭의 빈 자리를 채우는 방법

  • 일반적으로 PKCS#5, PKCS#7 사용

  • 나무위키

    PKCS#5 패딩은 PKCS#7 패딩과 구현 방식이 같지만 블럭의 크기가 8바이트로 고정된 것이다. AES는 128비트(16바이트) 블럭 알고리즘이기 때문에 사실 PKCS#5 패딩을 쓸 일이 없다. 그러나 PKCS#7 패딩과 구현 방식이 같아 보통 같은 구현을 돌려쓰는데다, Java에서 'AES/CBC/PKCS5Padding' 표기법만 허용하고 'AES/CBC/PKCS7Padding' 표기법은 지원하지 않다보니 오히려 AES에 PKCS#5 패딩을 쓰는 것이 맞는 줄 아는 경우가 많다.

Mode/IV
  • IV(Initialization Vector): 초기화 벡터

  • https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation

  • 블럭 암호화 순서 및 규칙에 대한 표준

  • CBC(Cipher-Block Chining)

    • 최초 평문 1블럭과 IV를 XOR 연산하고 암호화

    • 다음 편문 1블록은 앞에서 위에어 암호화된 결과 블럭에 XOR 연산하여 다시 암호화

    • 이 과정을 끝까지 반복하는 것이 CBC

    • 평문 마지막 블럭은 패딩된 블럭

  • ECB

    • IV를 사용하지 않고, 즉 XOR 연산 없이 각 블럭을 암호화

RSA

  • 공개키 암호 방식(public-key cryptography)의 한 종류

  • 비대칭키 사용

  • 1978년 로널드 라이베스트(Ron Rivest), 아디 샤미르(Adi Shamir), 레너드 애들먼(Leonard Adleman)의 연구에 의해 체계화되었으며, 이들 이름을 따서 명명됨

MAC, Message Authenication Code

HMAC, Hash-based Message Authentication Code

HMAC-SHA256

  • 절차

    1. 보내는 쪽에서 payload와 signature(payload + altorithm(HMAC_SHA256) + key)를 전달함

    2. 받는 쪽에서 전달 받은 payload로 signature를 만들어 전달 받은 signature와 동일한지 비교

  • 해시 함수를 통과하기 전 데이터를 message라 함. (payload = message)

  • 해시 함수를 통과한 데이터는 digest라 함. (signature = digest)

  • SHA-256 해시 알고리즘을 사용했으므로 다이제스트는 256 bytes