U+ 2024 Security Hackathon

goldenGlow_21·2024년 11월 17일
0

CTF 기록

목록 보기
2/4

회고 - Encryptor(Rev)

문제 해결 주요 과정

main 실행 및 구조 분석

  • main은 암호화된 입력 파일을 읽고, 특정 연산 후 .enc 확장자를 추가한 파일을 출력
  • stringsIDA로 실행 파일을 분석하여 다음과 같은 정보를 추출:
    - 입력 파일을 bit shuffleXOR 연산으로 암호화
    • rand() 함수 호출로 난수 시퀀스를 생성
    • srand(time(0))를 사용했기 때문에, 실행 시점의 timestamp를 복원하면 동일한 난수 시퀀스를 재현 가능

난수 시퀀스 복구

  • 문제에서 flag.png.enc의 수정 시간을 통해 정확한 time(0) 값을 계산
  • Python의 random 모듈로 동일한 난수 시퀀스를 재현하여 암호화 시 사용된 난수를 추출

복호화 로직 구현

  • main 파일의 디컴파일된 코드를 기반으로 복호화 과정 구현:
    • 비트 순서를 섞은 데이터의 역변환(reverse_bit_shuffle)
    • XOR 변환을 제거
    • 데이터 블록마다 적용된 체크섬 계산을 검증
  • Python 스크립트로 복호화 과정을 작성하여 flag.png.enc를 입력으로 받아 flag.png를 생성

결과 확인

  • 복호화된 flag.png를 열어 플래그를 확인

회고 시의 특기사항

암호화 방식 분석

  • 암호화는 단순한 bit shuffleXOR 기반으로 구현.
  • 암호화 과정에서 난수 시퀀스가 결정적(srand(time(0)))으로 생성되었기 때문에 복구가 가능

취약점 파악

  • 난수 시퀀스의 결정론적 인자 사용은 보안상 큰 취약점:
    - 공격자가 실행 시점의 time(0) 값을 복원하면 동일한 난수 시퀀스를 재현할 수 있음
  • 복호화 과정의 단순성:
    • 암호화 알고리즘이 공개되어 있었기 때문에, 로직 분석을 통해 복호화가 가능

문제 풀이에서 배운 점

  • 난수 시퀀스 생성에 있어 time(0)과 같은 간단한 시드 값은 사용하지 않아야 함
  • 복호화 로직 구현 시, 암호화 알고리즘의 동작을 이해하고 정확히 역변환을 수행해야 함

성공 코드

import ctypes
from ctypes import CDLL

libc = CDLL("libc.so.6")

def block_checksum(block):
    x = 0
    for i in range(7):
        x = x ^ block[i]
        for j in range(8):
            if ctypes.c_int8(x).value < 0:
                x = x * 2 ^ 7
                x &= 0xff
            else:
                x = x << 1
                x &= 0xff
    return x

def decrypt_block(block):
    found = False

    block = list(block)

    for i in range(8):
        for j in range(8):
            test_block = block[::]
            test_block[i] ^= 1 << j

            if block_checksum(test_block) == test_block[7]:
                block = test_block
                found = True
                break
        if found:
            break

    bits = []
    for i in range(7):
        for j in range(8):
            bits.append((block[i] >> j) & 1)

    swap_offset = libc.rand() % 7
    for i in range(55, -1, -1):
        if i + swap_offset < 56:
            temp = bits[i]
            bits[i] = bits[i + swap_offset]
            bits[i + swap_offset] = temp

    dec_block = [0] * 7
    for i in range(7):
        for j in range(8):
            dec_block[i] |= bits[i * 8 + j] << j

    return bytes(dec_block)

enc = open("./flag.png.enc", 'rb').read()
libc.srand(1730806261)

dec = b''

for i in range(len(enc) // 8):
    dec += decrypt_block(enc[i * 8:(i * 8 + 8)])

out = open(f'./flag.png', 'wb')
out.write(dec)
out.close()

print('Complete!')

놓친 점

  • **체크섬 검증과 역변환

    • 기존 접근에서 block_checksum과 같이 데이터를 검증하며 역변환하는 과정을 제대로 수행하지 못함
    • 특히, 변조된 비트를 확인하고 복구하는 과정을 소홀히 했습니다.
  • 비트 셔플링의 순서

    • 암호화 과정에서 비트들이 랜덤하게 섞였기 때문에 이를 역순으로 정확히 복구해야 했음
    • 기존 시도에서는 이 역순 변환 과정을 놓쳤거나 잘못 구현
  • 블록 단위 작업

    • 데이터가 8바이트씩 분리되어 7바이트 데이터와 1바이트 체크섬으로 구성된 구조임을 알았으나, 이를 블록 단위로 다루는 데 실패

코드 설명

체크섬 검증 함수: block_checksum

  • 목적: 블록의 데이터 무결성을 검증하기 위한 체크섬 계산
  • 과정:
    1. 첫 번째 바이트부터 7바이트까지 XOR 연산으로 값을 누적
    2. 누적된 값을 비트 시프트 및 특정 조건(<0)에 따라 조작
    3. 결과적으로 1바이트 크기의 체크섬 값을 반환
def block_checksum(block):
    x = 0
    for i in range(7):
        x = x ^ block[i]
        for j in range(8):
            if ctypes.c_int8(x).value < 0:
                x = x * 2 ^ 7
                x &= 0xff
            else:
                x = x << 1
                x &= 0xff
    return x

블록 복호화 함수: decrypt_block

  • 목적: 암호화된 블록(8바이트)을 복호화하여 원래 데이터를 복구
  • 과정:
    1. 비트 플립 탐색:
      • 블록의 모든 비트를 뒤집어 체크섬과 일치하는 블록을 찾음
      • 변조된 비트를 복구
    2. 비트 배열 변환:
      • 7바이트 데이터를 비트 배열로 변환
    3. 역 셔플링:
      • 암호화 시 수행된 비트 섞기를 랜덤 오프셋(swap_offset)을 기반으로 역변환
    4. 복호화된 데이터 생성:
      • 복원된 비트 배열을 다시 7바이트 데이터로 변환
def decrypt_block(block):
    found = False

    block = list(block)

    for i in range(8):
        for j in range(8):
            test_block = block[::]
            test_block[i] ^= 1 << j

            if block_checksum(test_block) == test_block[7]:
                block = test_block
                found = True
                break
        if found:
            break

    bits = []
    for i in range(7):
        for j in range(8):
            bits.append((block[i] >> j) & 1)

    swap_offset = libc.rand() % 7
    for i in range(55, -1, -1):
        if i + swap_offset < 56:
            temp = bits[i]
            bits[i] = bits[i + swap_offset]
            bits[i + swap_offset] = temp

    dec_block = [0] * 7
    for i in range(7):
        for j in range(8):
            dec_block[i] |= bits[i * 8 + j] << j

    return bytes(dec_block)

파일 복호화

  • 목적: 암호화된 파일을 블록 단위로 읽어 원본 데이터를 복호화
  • 과정:
    1. 암호화된 데이터를 8바이트씩 나눔
    2. 각 블록에 대해 decrypt_block 함수 호출
    3. 복호화된 데이터를 결합하여 원본 파일 생성
enc = open("./flag.png.enc", 'rb').read()
libc.srand(1730806261)  # 암호화 시 사용된 시드로 랜덤 시퀀스 재현

dec = b''

for i in range(len(enc) // 8):
    dec += decrypt_block(enc[i * 8:(i * 8 + 8)])

out = open(f'./flag.png', 'wb')
out.write(dec)
out.close()

print('Complete!')

회고 - Kkkk(Crypto)

1. ECDSA 소개

1.1 디지털 서명의 개념

  • 디지털 서명이란 무엇인가?
  • 디지털 서명의 주요 특징:
    • 데이터 무결성
    • 인증
    • 부인 방지

1.2 ECDSA 개요

  • ECDSA의 정의와 목적
  • 기존 DSA와의 차이점
    • DSA (Digital Signature Algorithm)의 확장
    • 타원 곡선을 활용한 키 크기 및 효율성 개선

2. 타원 곡선 암호학 기초

2.1 타원 곡선이란?

  • 타원 곡선의 정의:
    • 일반적인 방정식: y2=x3+ax+by2=x3+ax+b
    • ECDSA에서 사용되는 Weierstrass 형태
  • 타원 곡선의 시각적 이해:
    • 곡선 위의 점의 분포
    • 군 연산의 의미

2.2 군 이론과 타원 곡선

  • 군 연산의 정의:
    • 점 덧셈 (Point Addition)
    • 점 두 배 연산 (Point Doubling)
  • 군의 성질:
    • 교환법칙, 결합법칙
    • 항등원과 역원의 존재
  • 타원 곡선 군의 응용:
    • 비밀키와 공개키의 관계
    • 점 곱 연산의 계산 복잡성과 안전성

2.3 유한체(Galois Field)에서의 타원 곡선

  • 유한체의 정의와 성질
    • GF(p)GF(p): 소수 p를 모듈로 하는 체
  • 유한체 위의 타원 곡선:
    • 유한한 점 집합의 구성
    • 점 곱 연산의 정의
  • 암호학에서의 응용:
    • 유한체에서의 비대칭 키 암호

3. ECDSA의 수학적 원리

3.1 주요 구성 요소

  • 타원 곡선 파라미터:
    • 소수 체 p, 곡선 파라미터 a,b
    • 기본점 G, 군의 순서 n
  • 개인키와 공개키의 관계:
    • 개인키 d: 비밀 값
    • 공개키 Q=dGQ=d⋅G

3.2 서명 생성 과정

  1. 해시 값 계산:
    • 서명할 메시지를 SHA-256 등으로 해싱하여 hhh 생성
  2. 랜덤 Nonce 생성:
    • 난수 k 생성 (1≤k<n)
  3. 서명 값 계산:
    • R=kGR=k⋅G에서 x-좌표를 r로 정의
    • s=k1(h+rd)mod  ns=k^−1 (h+r⋅d)mod  n

3.3 서명 검증 과정

  1. 서명 값 검증:
    • 입력: 메시지 해시 hhh, 공개키 QQQ, 서명 (r,s)(r, s)(r,s)
    • 조건: 1r,s<n1≤r,s<n
  2. 검증 식 계산:
    • u1=hs1mod  nu1=hs1modnu1=hs1modnu1=h⋅s−1mod  nu_1 = h \cdot s^{-1} \mod nu1​=h⋅s−1modn
    • u2=rs1mod  nu2=rs1modnu2=rs1modnu2=r⋅s−1mod  nu_2 = r \cdot s^{-1} \mod nu2​=r⋅s−1modn
    • V=u1G+u2QV=u1G+u2QV=u1G+u2QV=u1⋅G+u2⋅QV = u_1 \cdot G + u_2 \cdot QV=u1​⋅G+u2​⋅Q
    • 검증: r=?xr \stackrel{?}{=}x-좌표 of VV

3.4 공격 가능한 부분

  • Nonce k의 재사용:
    • 동일한 k로 다른 메시지를 서명하면 d 복구 가능
  • Nonce k의 상관관계:
    • k가 결정론적으로 생성되거나 일부 알려질 경우 취약

4. 문제에 적용된 ECDSA의 취약점

4.1 문제의 주요 취약점 분석

  • 랜덤 Nonce k의 생성 방식:
    • k=mulk+inck=mul⋅k+inc
    • mul, inc가 고정되어 있어 k가 예측 가능
  • 서명 요청에서 kkk의 상관관계를 유도:
    • 다수의 서명을 통해 kkk의 관계를 식별

4.2 개인키 ddd 복구 방법

  1. 두 서명 (r1,s1),(r2,s2)(r1,s1),(r2,s2)에서의 관계:
    • r1=r2r1=r2​: 동일한 k가 사용됨
    • s1=k1(h1+r1d)s1=k^−1(h1+r1⋅d)
    • s2=k1(h2+r2d)s2=k^−1(h2+r2⋅d)
  2. kkk 제거 및 개인키 계산:
    • d=(s1h2s2h1)/(s2r1s1r2)modnd=(s1⋅h2−s2⋅h1) / (s2⋅r1−s1⋅r2) mod n

5. SageMath를 활용한 문제 풀이

5.1 SageMath로 수학적 계산하기

  • 서명 관계를 입력하여 연립방정식 풀이
  • 타원 곡선 연산을 활용하여 개인키 ddd 복구

5.2 스크립트 예제

  • SageMath 스크립트를 사용한 개인키 계산 과정
  • 복구한 개인키로 문제 해결

6. 결론

6.1 이번 문제를 통해 배운 점

  • ECDSA의 수학적 원리와 구조적 취약점
  • 랜덤 Nonce의 중요성

6.2 추가 학습 방향

  • 타원 곡선 암호학의 심화 학습
  • SageMath 및 암호 분석 도구 활용 능력 강화

1. ECDSA 소개

1.1 디지털 서명의 개념

디지털 서명은 현대 암호학에서 데이터를 보호하고 인증하는 데 중요한 기술입니다. 디지털 서명은 물리적 문서의 서명과 유사한 역할을 하지만, 전자 문서나 데이터를 위한 것으로, 데이터의 출처를 확인하고 데이터가 위변조되지 않았음을 보장합니다. 이를 위해 디지털 서명은 공개 키 암호화를 기반으로 동작하며, 데이터를 서명한 개인의 비밀키와 이를 검증할 수 있는 공개키로 구성됩니다.

디지털 서명의 주요 역할

  1. 데이터 무결성 보장

    • 디지털 서명은 데이터가 전송 중 변경되지 않았음을 보장
    • 서명을 생성할 때 데이터의 해시값이 사용되므로, 데이터가 변경되면 해시값도 달라져 서명이 무효
    • 이를 통해 데이터가 위변조되었는지 확인할 수 있음
  2. 인증 (Authentication)

    • 서명은 특정 개인이나 엔터티의 비밀키로만 생성 가능
    • 수신자는 서명된 데이터를 공개키로 검증함으로써 서명자가 데이터를 생성했음을 확인 가능
    • 예를 들어, 은행에서 보낸 디지털 서명된 문서는 수신자가 은행의 공개키로 검증할 수 있어, 문서의 출처를 확인할 수 있음
  3. 부인 방지 (Non-repudiation)

    • 서명자는 자신의 비밀키로 데이터를 서명했기 때문에, 이후 서명 사실을 부인할 수 없음
    • 이는 계약서나 법적 문서의 전자 서명에 매우 유용하며, 서명자가 데이터를 생성하고 보냈음을 증명하는 데 사용

디지털 서명의 작동 원리

디지털 서명은 대체로 다음 세 단계로 작동합니다.

  1. 서명 생성 (Signing)

    • 서명자는 데이터를 해시 함수를 사용하여 고정된 길이의 해시값을 계산
    • 계산된 해시값은 서명자의 비밀키로 암호화되어 서명을 생성
  2. 서명 전달 (Transmission)

    • 서명자는 원본 데이터와 디지털 서명을 수신자에게 전송
  3. 서명 검증 (Verification)

    • 수신자는 데이터를 해싱하여 새로운 해시값을 계산
    • 서명은 서명자의 공개키로 복호화되어 서명 시 사용된 해시값을 복원
    • 복원된 해시값과 새로 계산된 해시값이 일치하면, 데이터의 무결성과 서명자의 인증이 검증

디지털 서명의 구조

디지털 서명은 일반적으로 두 가지 구성 요소로 이루어져 있습니다.

  • 개인키 (Private Key)
    서명을 생성하는 데 사용되며, 서명자만이 알고 있는 비밀키
    이 키는 절대로 다른 사람과 공유되어서는 안 됨

  • 공개키 (Public Key)
    서명을 검증하는 데 사용되며, 서명자가 다른 사람에게 공개할 수 있음
    이 키는 데이터를 암호화하는 데 사용되지 않으므로, 공유해도 보안에 문제가 없음

디지털 서명의 주요 특징

  1. 안전성 (Security)

    • 디지털 서명은 개인키와 공개키의 수학적 연관성을 기반으로 동작
    • 개인키를 알지 못하면 애초에 서명을 위조할 수 없음
  2. 효율성 (Efficiency)

    • 디지털 서명은 짧은 시간 안에 서명 생성 및 검증이 가능
    • 네트워크와 컴퓨팅 리소스의 사용을 최적화
  3. 표준화 (Standardization)

    • 디지털 서명은 다양한 표준 프로토콜(예: RSA, DSA, ECDSA)에 따라 설계되어 상호운용성이 뛰어남

디지털 서명의 응용 분야

  1. 전자 상거래

    • 디지털 서명은 온라인 트랜잭션에서 고객과 판매자 간 신뢰를 구축하는 데 사용
  2. 전자 계약

    • 디지털 서명은 법적 구속력이 있는 계약서에 사용되며, 계약 당사자의 인증과 계약 내용의 무결성을 보장
  3. 소프트웨어 배포

    • 디지털 서명은 소프트웨어 개발자가 배포한 프로그램이 위변조되지 않았음을 보증하는 데 사용
  4. 정부 및 공공 서비스

    • 전자 여권, 디지털 신분증, 전자 투표 시스템 등에서 디지털 서명이 사용

디지털 서명의 장점과 단점

장점단점
데이터의 인증 및 무결성을 보장비밀키 유출 시 서명 위조 가능
서명자의 부인 방지서명 생성 및 검증에 연산 자원이 필요
네트워크 및 데이터 저장 비용 절감암호학적 안전성에 대한 의존

디지털 서명은 현대 정보사회에서 데이터의 신뢰성과 보안을 보장하기 위해 필수적인 기술로 자리 잡고 있습니다. ECDSA는 이러한 디지털 서명 기술 중 하나로, 높은 보안성과 효율성을 제공합니다.

1.2 ECDSA 개요

ECDSA(Elliptic Curve Digital Signature Algorithm)는 디지털 서명의 한 형태로, 기존의 DSA를 타원 곡선 암호학으로 확장한 알고리즘입니다. 주요 장점은 다음과 같습니다.

  • 짧은 키 크기: 동일한 보안 강도를 유지하면서 기존 DSA나 RSA보다 훨씬 짧은 키 크기를 가짐
  • 높은 성능: 키 생성, 서명, 검증 속도가 빠름
  • 효율적 저장: 짧은 키 크기로 인해 메모리 및 대역폭 효율성이 높음

ECDSA는 타원 곡선의 군 연산을 기반으로 동작하며, 암호학적 안전성을 제공합니다.


2. 타원 곡선 암호학 기초

2.1 타원 곡선이란?

타원 곡선은 다음과 같은 형태의 방정식으로 정의됩니다.

y2=x3+ax+by^2=x^3+ax+b

여기서 a와 b는 곡선의 형태를 결정하는 파라미터이며, x와 y는 곡선 위의 점을 나타냅니다.

  • a, b: 곡선의 형태를 결정하는 상수
  • x, y: 곡선 위의 점을 나타내는 좌표
  • p: 소수(Prime Number)로, 유한체에서의 계산을 위해 사용

타원 곡선은 암호학에서 다음과 같은 특성을 가집니다.

  • 대칭성:

    • 타원 곡선 위의 모든 점 P(x,y)P(x, y)P(x,y)에 대해 P′(x,−y)P'(x, -y)P′(x,−y)도 곡선 위에 존재
    • 이 두 점은 xxx-축에 대해 대칭
  • 곡선 위의 점들의 연산 가능:

    • 곡선 위의 점들은 특정 연산 규칙을 통해 새로운 점을 생성할 수 있음
    • 이러한 연산은 암호학의 핵심
  • 암호학적 응용:

    • 타원 곡선은 키 크기에 비례하여 높은 보안성을 제공
    • 상대적으로 작은 키 크기로도 RSA와 같은 기존 암호 알고리즘과 비슷한 수준의 보안을 제공

2.2 군 이론과 타원 곡선

군(Group)의 정의

군은 수학적 구조로, 다음과 같은 성질을 만족하는 집합과 연산의 쌍입니다:

  1. 폐쇄성: 두 원소의 연산 결과가 항상 집합의 원소입니다.
  2. 결합법칙: 연산은 결합법칙을 만족합니다.
    (a+b)+c=a+(b+c)(a+b)+c=a+(b+c)
  3. 항등원 존재: 집합에는 항등원이 존재하며, 연산 후 원소가 변하지 않습니다.
  4. 역원 존재: 각 원소는 자신의 역원이 존재하여, 연산 결과가 항등원이 됩니다.

타원 곡선 위의 점들로 이루어진 군

타원 곡선 위의 점들은 군의 성질을 가집니다. 여기서 연산은 점 덧셈(Point Addition)과 점 두 배(Point Doubling)로 정의됩니다.
곡선 위의 점들과 군 연산은 암호학적 작업의 기본 단위입니다.

  1. 덧셈 연산 (Point Addition):
    두 점 P(x1,y1),Q(x2,y2)P(x1,y1), Q(x2,y2)에 대해, R=P+QR=P+Q는 다음과 같이 계산됩니다:

    • 기울기: m=y2y1x2x1(modp)m = \frac{y_2 - y_1}{x_2 - x_1} \pmod{p}
    • 새로운 점: x3=m2x1x2(modp),y3=m(x1x3)y1(modp)x_3 = m^2 - x_1 - x_2 \pmod{p}, \quad y_3 = m(x_1 - x_3) - y_1 \pmod{p}
  2. 점 두 배 (Point Doubling):
    P(x1,y1)P(x1,y1)에 대해 R=2PR=2P는 다음과 같이 계산됩니다:

    • 기울기: m=3x12+a2y1(modp)m = \frac{3x_1^2 + a}{2y_1} \pmod{p}
    • 새로운 점: x3=m22x1(modp),y3=m(x1x3)y1(modp)x_3 = m^2 - 2x_1 \pmod{p}, \quad y_3 = m(x_1 - x_3) - y_1 \pmod{p}
  3. 스칼라 곱 (Scalar Multiplication):

    • kPk⋅P: 점 P를 k번 더한 결과입니다.
    • 이 연산은 효율적으로 계산하기 위해 Double-and-Add Algorithm 같은 방법이 사용됩니다.

2.3 유한체(Galois Field)에서의 타원 곡선

유한체 GF(p)GF(p)

유한체는 정수 집합 {0,1,2,...,p1}\{0, 1, 2, . . ., p-1\}에서 덧셈과 곱셈을 모듈로 p 연산으로 정의한 체(Field)입니다. 여기서 p는 소수(Prime Number)여야 하며, 연산 결과는 항상 p로 나눈 나머지가 됩니다. 즉,

  • 덧셈:
    (a+b)modp(a + b) \mod p

  • 곱셈:
    (ab)modp(a \cdot b) \mod p

  • 역원:
    a에 대해 b가 존재하여 ab1(modp)a \cdot b \equiv 1 \pmod{p}

유한체에서의 타원 곡선

암호학에서는 유한체 GF(p) 위에서 타원 곡선을 정의합니다. 유한체를 사용하면 타원 곡선 위의 점의 개수가 유한하며, 이 점들의 집합으로 군을 형성할 수 있습니다.

  • 곡선의 정의:
    y2x3+ax+b(modp)y^2 \equiv x^3 + ax + b \pmod{p}

  • 곡선 위의 점들:
    모든 가능한 x,yGF(p)x, y \in GF(p)를 대입하여 방정식을 만족하는 점들을 찾습니다.

  • 군의 크기 (Order):
    곡선 위의 점들의 총 개수는 군의 크기로, 곡선의 보안 강도에 직접적인 영향을 미칩니다.

타원 곡선 난이도 문제 (ECDLP)

타원 곡선 암호학의 보안은 타원 곡선 이산 로그 문제 (Elliptic Curve Discrete Logarithm Problem, ECDLP)에 기반합니다:

  • P,QE(Fp)P, Q \in E(F_p)에 대해, Q=kPQ = k \cdot P일 때, k를 구하는 것은 매우 어렵습니다.

이 문제의 계산 복잡도는 기존의 이산 로그 문제보다 훨씬 높아, 같은 보안 강도를 가진 암호 알고리즘에서 필요한 키 크기를 크게 줄일 수 있습니다. 예를 들어, 256비트의 타원 곡선 암호는 약 3072비트의 RSA 키와 비슷한 보안을 제공합니다.


3. ECDSA의 수학적 원리

c.f: https://blog.naver.com/aepkoreanet/221178375642

3.1 주요 구성 요소

  1. 타원 곡선 파라미터:

    • p: 소수 체(모듈러스)
    • a,b: 곡선의 정의
    • G: 기본점(Generator Point)
    • n: 기본점의 순환군의 크기(Order)
  2. 키 구성:

    • 개인키 d: 임의의 정수 1d<n1 \leq d < n
    • 공개키 Q:Q=dGQ: Q = d \cdot G, 개인키에 기본점을 곱한 값

3.2 서명 생성 과정

  1. 메시지 해싱:
    • 메시지 M을 SHA-256 등으로 해싱하여 h 생성.
  2. 랜덤 Nonce k 생성:
    • k는 서명 과정에서 매번 새롭게 생성되는 난수
  3. 서명 값 계산:
    • R=kG,r=x 좌표 of RR = k \cdot G, \quad r = x \text{ 좌표 of R}
    • s=k1(h+rd)modns = k^{-1} \cdot (h + r \cdot d) \mod n
    • 최종 서명은 (r,s)

3.3 서명 검증 과정

  1. 입력:
    • 메시지 M, 서명 (r,s), 공개키 Q
  2. 계산:
    • u1=hs1modn,u2=rs1modnu_1 = h \cdot s^{-1} \mod n, \quad u_2 = r \cdot s^{-1} \mod n
    • V=u1G+u2QV = u_1 \cdot G + u_2 \cdot Q
  3. 검증: r=?x 좌표 of Vr \stackrel{?}{=} x \text{ 좌표 of } V

3.4 취약점

  1. Nonce k의 재사용:
    • 동일한 k로 다른 메시지를 서명하면 d를 복구 가능
  2. Nonce k의 상관관계:
    • k가 결정론적으로 생성되거나 일부 노출되면 공격 가능

4. 문제 분석

4.1 랜덤 Nonce k 생성 취약점

문제에서 k는 다음과 같이 생성:

k=mulk+inck = \text{mul} \cdot k + \text{inc}

여기서 mul\text{mul}inc\text{inc}는 고정된 값이라고 가정하면 k가 난수처럼 보이지만 결정론적 관계를 가지므로 k 간의 상관관계를 분석할 수 있을 것


5. 수학적 풀이

5.1 Nonce 재사용 공격

두 개의 서명 (r1,s1),(r2,s2)(r1,s1), (r2,s2)가 동일한 k로 생성되었다면, 다음 관계를 이용해 d를 복구할 수 있을 것

d=s1h2s2h1s2r1s1r2modnd = \frac{s_1 \cdot h_2 - s_2 \cdot h_1}{s_2 \cdot r_1 - s_1 \cdot r_2} \mod n


6. 학습 내용 요약

  • ECDSA의 강점: 짧은 키 크기와 효율적인 서명/검증 속도.
  • 취약점: Nonce k의 안전한 생성이 중요.
  • 학습 방향:
    • 타원 곡선 암호학 심화 학습
    • SageMath를 활용한 자동화된 분석
profile
안드로이드는 리눅스의 꿈을 꾸는가

0개의 댓글

관련 채용 정보