김보안의 블로깅
  • 🏠 Home
  • 📚 Project
    • Blockchain
      • 🎦 PickMe
      • 🎦 IoTC
      • 🎦 Blackchain
      • 📃 Gemology
      • 🎦 PickMe
      • 🎦 PickMe
    • AI
      • 👋 A.I. Dream Reader
      • 🎦 A.I. Dream Reader
    • Security
      • 🎦 SNAC
    • Education
      • 🎦 Smart Lecture
  • 🤸‍♂ Hobby
    • Music
      • Violin
      • Guitar
      • Piano
      • Drum
    • Flower
      • Flower Certificate
    • Sport
      • Ski
      • Skateboard
      • Golf
      • Boxing
레이블이 Encrypt인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Encrypt인 게시물을 표시합니다. 모든 게시물 표시

2026년 2월 25일 수요일

태블릿에서 양자내성암호(격자암호) 돌려보기

 SecureKim     오후 7:30     Encrypt, Lattice-based Cryptography, Quantum, Security     No comments   

 

Termux에서 양자 내성 암호 돌려보기

많은 시행 착오 끝에 성공 !


1. Playstore에서 Termux를 설치한다.


2. 양자 내성 암호 라이브러리 빌드를 위한 셋업


pkg update && pkg upgrade -y

pkg install clang cmake ninja python git -y

pip install setuptools


3. 양자내성암호 소스코드 직접 빌드 (pip로 하면 안됨)

git clone -b main https://github.com/open-quantum-safe/liboqs.git 

cd liboqs 

mkdir build && cd build


- 잦은 에러를 유발 알고리즘 (NTRU Prime) 제외하고 ML-KEM 활성화 설정해서 cmake

cmake -GNinja .. -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=$PREFIX -DOQS_USE_OPENSSL=OFF -DOQS_KEM_DEFAULT=OFF -DOQS_SIG_DEFAULT=OFF -DOQS_KEM_ML_KEM=ON -DOQS_ENABLE_KEM_NTRUPRIME=OFF


- 빌드

ninja install


- 잘 빌드 되었는지 확인

export LD_LIBRARY_PATH=$PREFIX/lib:$LD_LIBRARY_PATH python -c "import oqs; print('ML-KEM 성공 여부:', 'KeyEncapsulation' in dir(oqs))"


4. C로 만든 엔진을 python에서 쓸 수 있도록 연결

pip install liboqs-python 

# 파이썬이 라이브러리를 찾을 수 있도록 경로 설정

export LD_LIBRARY_PATH=$PREFIX/lib:$LD_LIBRARY_PATH


5. 예제

pip install pycryptodome


import oqs, hashlib, binascii, os

from Crypto.Cipher import AES

from Crypto.Util.Padding import pad, unpad


# 1. ML-KEM 기반 키 교환 (양자 내성)

with oqs.KeyEncapsulation("ML-KEM-768") as alice:

    alice_pub = alice.generate_keypair()

    with oqs.KeyEncapsulation("ML-KEM-768") as bob:

        ciphertext, bob_secret = bob.encap_secret(alice_pub)

    alice_secret = alice.decap_secret(ciphertext)


# 2. 6자리 인증 코드 생성 (중간자 공격 방지)

auth_code = hashlib.sha256(alice_secret).hexdigest()[:6]

print(f"[*] 인증 코드 확인: {auth_code}")


# 3. AES-256-CBC 암호화 통신

key = hashlib.sha256(alice_secret).digest()

iv = os.urandom(16)

msg = "양자 보안 메시지입니다."


# 암호화

cipher = AES.new(key, AES.MODE_CBC, iv)

enc_msg = cipher.encrypt(pad(msg.encode(), 16))

print(f"[-] 암호문: {binascii.hexlify(enc_msg[:10])}...")


# 복호화

dec_cipher = AES.new(key, AES.MODE_CBC, iv)

dec_msg = unpad(dec_cipher.decrypt(enc_msg), 16).decode()

print(f"[+] 복호화 결과: {dec_msg}")








Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

2018년 1월 24일 수요일

Node.js 에서 RSA 로 암복호화 하기

 SecureKim     오전 12:34     암복호화, decrypt, Encrypt, Node.js, RSA, Security     3 comments   


Node.js 의 crypto 모듈은 기본적으로 제공되므로, npm 으로 설치할 필요가 없습니다.

crypto 기본 모듈을 사용해 RSA 의 키로 암복호화 하는 방법을 알아 봅시다.

일단 그 전에 OpenSSL로 RSA Private Key, Public Key 를 생성합니다.


C:\Users\Public>openssl genrsa -out private.key 2048

Generating RSA private key, 2048 bit long modulus
.................................................................................................................................+++
.........+++
unable to write 'random state'
e is 65537 (0x10001)


예전 블로그의 AES 관련 글 을 보시면 아시다시피,

Private key 로 Public key 를 Generate 할 수 있습니다.

C:\Users\Public>openssl rsa -in private.key -out public.key -pubout

그런데 단순히 이렇게 하시면, 결과가 PKCS#8 표준으로 나옵니다.

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuErwCGWyq3nIASTKhgiH
GAaURZ9rs5EBR9L1YUJh1ftYgQSt0gUzab6hyW/upgM4Z4Mu6pA+KZCHncKc4SHJ
XdJvYnj1L6/RRinXQp+R3MmGypoB/r1ckM1aEt75/I0m7Dlatj58f56Z21yHsJNb
tf1LAD981a3kR6kaIb7Uc5bsUDwObF2r5xAenQDtaZoWgaErHWwiqzJJQebcAVVq
lq2/+f1kzRVqHsasosXOD6hrDz9oC2SvBKWVrmOPF4D+mwwaChEKAhFDvCKj5NYw
prmoOXWK6t5WroYvsVo5Sa039DiCPXMsug9MidhQLB7SpW7Bi+xeuwvObWppgGZ8
FQIDAQAB
-----END PUBLIC KEY-----

PKCS#8 표준의 ASN.1 구조를 보면 다음과 같습니다.
PublicKeyInfo ::= SEQUENCE {
  algorithm       AlgorithmIdentifier,
  PublicKey       BIT STRING
}

AlgorithmIdentifier ::= SEQUENCE {
  algorithm       OBJECT IDENTIFIER,
  parameters      ANY DEFINED BY algorithm OPTIONAL
}

우리는 PKCS#1 을 사용할 것이므로 아래와 같이 변환합니다.

C:\Users\Public>openssl rsa -pubin -in public.key -RSAPublicKey_out


-----BEGIN RSA PUBLIC KEY-----

MIIBCgKCAQEAuErwCGWyq3nIASTKhgiHGAaURZ9rs5EBR9L1YUJh1ftYgQSt0gUz
ab6hyW/upgM4Z4Mu6pA+KZCHncKc4SHJXdJvYnj1L6/RRinXQp+R3MmGypoB/r1c
kM1aEt75/I0m7Dlatj58f56Z21yHsJNbtf1LAD981a3kR6kaIb7Uc5bsUDwObF2r
5xAenQDtaZoWgaErHWwiqzJJQebcAVVqlq2/+f1kzRVqHsasosXOD6hrDz9oC2Sv
BKWVrmOPF4D+mwwaChEKAhFDvCKj5NYwprmoOXWK6t5WroYvsVo5Sa039DiCPXMs
ug9MidhQLB7SpW7Bi+xeuwvObWppgGZ8FQIDAQAB

-----END RSA PUBLIC KEY-----



PKCS#1 의 ASN.1 구조는 다음과 같습니다.
RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}

(참고로 반대로 ( PKCS#1 -> PKCS#8 ) 변환하는 하는 방법은 아래와 같습니다.)
openssl rsa -RSAPublicKey_in -in -pubout

이제 예제를 볼까요?



RSA encyrpt & decrypt in node.js


var crypto = require('crypto');

var PRIVKEY = '-----BEGIN RSA PRIVATE KEY-----\n'+
'MIIEowIBAAKCAQEAuErwCGWyq3nIASTKhgiHGAaURZ9rs5EBR9L1YUJh1ftYgQSt\n'+
'0gUzab6hyW/upgM4Z4Mu6pA+KZCHncKc4SHJXdJvYnj1L6/RRinXQp+R3MmGypoB\n'+
'/r1ckM1aEt75/I0m7Dlatj58f56Z21yHsJNbtf1LAD981a3kR6kaIb7Uc5bsUDwO\n'+
'bF2r5xAenQDtaZoWgaErHWwiqzJJQebcAVVqlq2/+f1kzRVqHsasosXOD6hrDz9o\n'+
'C2SvBKWVrmOPF4D+mwwaChEKAhFDvCKj5NYwprmoOXWK6t5WroYvsVo5Sa039DiC\n'+
'PXMsug9MidhQLB7SpW7Bi+xeuwvObWppgGZ8FQIDAQABAoIBAQCPOcYkcI0UETgs\n'+
'E2DGHBiJxoszNLuqOVaKcFw9sy5/87ALzQwdvecAFqR7/d617KjIYb5zk5iMCwQq\n'+
'ylXL7csmfGYOXL0Iy5ZT9i6SW5srwP9ds6U7SgWHj+Ch6+LSsQx/5+8k1ZlCQYuH\n'+
'XPkjdNKAtJK2ZaDqHBPe0YA6m6lXDrEOJl6xrlUWCZS02XPIXFaB+qTBG2UqWCUK\n'+
'KzVa9qIqWf3bVGJCLc70u5UiuvCC+V8VtJ964AEnj90qZy1tRhEc2X8bbWmhL3yB\n'+
'3SLWH4ZvJyEDQe/yycx9rO6CymDj3c378IyWORYt1y6mKRmltr2NJ1Ecbl9xaFrc\n'+
'JeVO8wDdAoGBAOUjZzuaVppccEIiBbLS0NksSeD4tfjlUPFqVU1obZcbkDugK1Id\n'+
'og+W5yVy2NqgeEi4nQ9Ogi485cWbCzTZM52d9zuFe/60hBFPU8jWxafW0OW2o6ci\n'+
'F1vtzWEF2EO7omUoiGu6mOI4yRcUMwXiw1cCWr2NYpASQ39QuxwXKgg7AoGBAM3l\n'+
'sC7nxqDusq+J9CI6V+oNb2v7KgapQmrdXNB5l6Mk2Dl/uNfuX5cDceMQlO5B/ObT\n'+
'44kgsBR3tO6y7PQLDClt5ZPrVJZ16+cCj41UDDgZDD0vDaU24K/qSVrsOH4gNgeM\n'+
'CcsInzX/l1bm+RAhE0pHuPHBZFuLi8brV/wZCpfvAoGAQu4XbmKDn20W4UpczcIk\n'+
'fPshzVP4m24oOYwsxIKXWEcV10TOwpqjRth2RgsI6rtqxxsdzWXKQsVI/HJwUIyN\n'+
'NiH5IGq6MEj8Nq4sNAMAEyl9NUwm+1/K4PBSSF/Trt0070Vqq8UCeTnLCzG8QaDe\n'+
'HCE07h9JRfn/u0WSkf72KRcCgYAUTGmjJix53y50idgsq63RIEP01E0fXP50RKCK\n'+
'2QHvDonWmVXiy9hWrftDVHYqSw0gwJD1CujxC6AlzDP6F0C6sN/qRlAPiU6ZdrIq\n'+
'T7foq+d9/K6OtCtQjHtw4ErtfEV3VwH8Jzxy+WC1K44wXeJl904vX06Ci+5azQbe\n'+
'jqVxtwKBgBnxVKFQCmuDjOZrf7V0jB/mf4ir9npqvHdJMHE/Et70lOaUbhat6i+Y\n'+
'PPtJewynfF4zp+HD6jOlj4RhbCncMNdaWAyDYOucYOJOpMr5mIYJHdCOVQ0aSRD7\n'+
'/dZEOGblrch6VXOEvC++yaToNhjkeTP63IH4K6uqa9btelz3Df5Y\n'+
'-----END RSA PRIVATE KEY-----\n';

var PUBKEY = '-----BEGIN RSA PUBLIC KEY-----\n'+
'MIIBCgKCAQEAuErwCGWyq3nIASTKhgiHGAaURZ9rs5EBR9L1YUJh1ftYgQSt0gUz\n'+
'ab6hyW/upgM4Z4Mu6pA+KZCHncKc4SHJXdJvYnj1L6/RRinXQp+R3MmGypoB/r1c\n'+
'kM1aEt75/I0m7Dlatj58f56Z21yHsJNbtf1LAD981a3kR6kaIb7Uc5bsUDwObF2r\n'+
'5xAenQDtaZoWgaErHWwiqzJJQebcAVVqlq2/+f1kzRVqHsasosXOD6hrDz9oC2Sv\n'+
'BKWVrmOPF4D+mwwaChEKAhFDvCKj5NYwprmoOXWK6t5WroYvsVo5Sa039DiCPXMs\n'+
'ug9MidhQLB7SpW7Bi+xeuwvObWppgGZ8FQIDAQAB\n'+
'-----END RSA PUBLIC KEY-----\n';

// RSA PRIVATE ENCRYPT -> PUBLIC DECRYPT //
 myMSG = "[ORIGINAL] I'm securekim !!!";
 
function privENC_pubDEC(originMSG){
 encmsg = crypto.privateEncrypt(PRIVKEY, Buffer.from(originMSG, 'utf8') ).toString('base64');
 msg = crypto.publicDecrypt(PUBKEY, Buffer.from(encmsg, 'base64'));
 console.log("Encrypted with private key : "+encmsg);
 console.log(msg.toString());
}

function pubENC_privDEC(originMSG){
 encmsg = crypto.publicEncrypt(PUBKEY, Buffer.from(originMSG, 'utf8') ).toString('base64');
 msg = crypto.privateDecrypt(PRIVKEY, Buffer.from(encmsg, 'base64'));
 console.log("\nEncrypted with public key : "+encmsg);
 console.log(msg.toString());
}

privENC_pubDEC(myMSG);
pubENC_privDEC(myMSG);



  • 결과 :


Encrypted with private key : Q9Tz2LRlv91Rk2ScR/Wjv77ouDsiWyefVIKlssIYHBJihZeQ0IDH+rUCMG0aBhSDNT92zZjAmPF5Pah9xejqYsfCfDslmNp+FXvmfoA02uviW6b4A6e90U3atyU1PIZHtp4nDtIAYCvY78xzEyZ5oqwhbDcKuIcs4Uo4dtXNmo6N9/+Rxckf0ByCyRAUv86x1a6SYzgqyGthaDAnIUxFAXsJpAkrAOTeBy9PKx785DEXYDBOzgsFcZRHwMuFNFlMTYfQtW/rwPL0cSA6ud3Ew0Qsv4wY73ty46s2kYezSo6YjrHkYDotlhXLK5rqY+bBtU/SAufvhj/BDxYEDe9scQ==
[ORIGINAL] I'm securekim !!!

Encrypted with public key : CEhDVj/6KquMN5QRi69okZXz6gVjHKQGOm1C1CvBExRTQrKN8sMMT1wqTQpRdVzu+YUlidgCmj+v+5bgiSMl1Ul38VUHT9rL42fwT226RYfhlMvRn2umddboyHh0TMPwWqI6aQ/36DQqmuXN34Rk2It2qs5gERZWTJgRdQ1mYrrz7nOA5nnu/vZyOmk4PjYww9QediUF+J9pxOAlYsIT+AdOXVvdKeB6M5esGZWwQ3trZvklG0KmZSNUQ6HyvQ/+MorsKDMOZxpRcBxTB+3DzzUb+UtvBSlsUNYfnMAYlEeB7M4AzgIJpZ8jfYOecp9DSx6eTzk919YVCyUU3GL2oQ==

[ORIGINAL] I'm securekim !!!


일반적으로 각 함수가 사용되는 용도는 다음과 같습니다.

ㆍprivENC_pubDEC

   - Signature Verify
    예를 들어 상호 인증시 클라이언트는 이때까지 주고받은 내용을 Hash 한 다음
    Private key 로 암호화해 Signature 를 생성해 서버로 전달합니다.
    서버는 이때까지 주고받은 내용을 Hash 한 값과,
    클라이언트가 보내준 인증서의 Public key로 Signature 를 복호화 한 값을 비교하여
    동일한지 판단 합니다.

ㆍpubENC_privDEC

    - AES KEY nego
     클라이언트가 AES Key 를 서버의 Public key 로 암호화해서
     서버에게 전달 해 주면 서버에서는 복호화 합니다.
     이렇게 하여 클라이언트와 서버는 AES Key 를 나눠갖게 되고,
     이후 통신은 AES KEY로 하게 됩니다.

이후 통신을 AES KEY 로 암호화 하는 이유는 RSA 암호화 방식은 AES 에 비해 너무 느리기 때문입니다.

그리고 메시지의 길이가 긴 경우 아래와 같이 RSA 로 암호화가 되지 않습니다.

Error: error:0406C06E:rsa routines:RSA_padding_add_PKCS1_type_1:data too large for key size

다음 포스팅에서는 Node.js 에서 crypto 모듈을 사용해 AES 암호화를 해보겠습니다.

Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

2017년 9월 20일 수요일

[Kisa] 암호의 이해와 키 관리 실무 - 3일차 PKI 관련 표준 - PKCS

 SecureKim     오후 3:58     Encrypt, Key, KISA, PKCS, Security, Study     No comments   


PKI 관련 표준


CLR 

서버가 받은 인증서의 'CLR 배포 지점' 항목에서 LDAP URL(ldap://) 을 추출해
LDAP DB에 직접 쿼리.
CA에서는 LDAP DB를 항상 갱신함.
폐기된 인증서라도 만료일이 지나면 CLR목록에서 제외.

OCSP

실시간 인증서 상태 검증 프로토콜 (RFC 2560)

  • 인증서 폐기 후, 그 즉시 폐기 여부 조회 가능
  • 하나의 요청 트랜젝션에 여러 인증서의 상태 요구 가능
  • 통신에 대한 무결성을 보증 받을 수 있음
  • 인가된 사용자에게만 OCSP 서비스를 제공할 수 있음.
  • 프로토콜 자체 보안 기능(Replay Attack)을 제공
서버가 받은 인증서의 'Authority Info Access' 항목에서 OCSP URL을 추출해
OCSP 서버에 쿼리.
OCSP 서버가 LDAP 에 직접 폐기 여부를 조회하고, 조회 결과를 서버에 보내준다.
CA에서는 LDAP DB를 항상 갱신한다.
타기관 LDAP DB와 동기화 된다.

OCSP 서버가 대신하는거 말고 차이가 없어 보이는데...

REPLAY Attack 을 막기 위해 Nonce 를 랜덤하게 생성해서 보낸다. 
암호화 통신을 안한다면 Nonce 가 의미가 있는건지?,

CMP

  • 클라이언트에 인증서에 대한 실시간 관리(발급/갱신/폐기) 가능
  • CA간 상호인증 등 온라인 서비스 구현 가능
  • 통신에 대한 무결성 보증 가능
  • 통신 상대방 인증 가능
  • 프로토콜 자체 보안 기능 제공
사용자가 인증서 발급 신청을 하면, RA (은행 등) 에서 CA에 발급신청을 하고, 
CA에서는 RA로 인가 코드를 전송한다. 사용자는 이후 공개키 개인키를 생성하고 
RA로부터 전달 받은 인가 코드로 요청 자체를 HMAC 돌려서 CA에 보낸다.
이후 CA는 인증서를 발급 하고, LDAP 에 갱신한다.


결국 CMP 나 PKCS #10 이나 인증서 발급에는 다음과 같은 정보가 필요하다.
CRMF (사용자 식별 정보, 공개키, PoP(Proof of Possession))

POP란 서버에서 보낸 Random 값을 클라이언트의 개인키로 사인한 값이다.

CMP 인증서 발급시 패킷


CMP 인증서 갱신시 패킷
kur 에는 공개키, 개인키 Random 값을 서버의 공개키로 암호화, POP(signature)
+ extraCerts 안에 기존 인증서를 보냄.


발급(ip)과 갱신(kup)시 차이는?



PKCS

PKCS# 1 RSA Standard(PKCS­2/PKCS­4포함) 1.5 1993. 11 
PKCS# 3 Diffie­Hellman Key­Agreement Standard 1993. 11 
PKCS# 5 Password­Based Encryption Standard 1.5 1993. 
PKCS# 6 Extended­Certificate Syntax Standard 1.5 1993. 11
PKCS# 7 Cryptographic Message Syntax Standard 1.5 1993. 11
PKCS# 8 Private­Key Information Syntax Standard 1.2 1993. 11
PKCS# 9 Attribute Types 1.1 1993. 11
PKCS#10 Certification Request Syntax 1.0 1993. 11
PKCS#11 Cryptographic Token Interface Standard 2.01 12
PKCS#12 Personal Information Exchange Syntax Standard 1.0(Draft) 1997. 
PKCS#13 Elliptic Curve Cryptography Standard Project 진행중
PKCS#14 Generator Standard Project 진행중 

PKCS #1 : RSA Cryptography Standard

RSA 암호화/서명 방법과 공개키/개인키에 대한 ASN.1 표기법이 설명되어 있음.
  • RSA Public Key /Private Key : ASN.1 표기법 설명
  • 데이터 변환 방법 설명 : Integer를 OCTET String 으로 변환하는 방법 설명
  • RSAEP/RSADEP : 수하적인 공개키 암호화 스킴 설명
  • RSAES-PKCS1-V1_5 : 단순한 패딩 기법을 활용한 RSA 암호화 스킴 설명
  • RSASSA-PKCS1-V1_5 : 단순한 패딩 기법을 활용한 RSA 전자서명 스킴 설명
  • RSASP1/RSADVP1 : 수학적인 전자서명 스킴 설명
  • RSAES-OAEP : RSA 에 대한 공격에 안전한 암호화 스킴 설명(확률적 암호화)
  • RSASSA-PSS : RSA 에 대한 공격에 안전한 전자서명 스킴 설명
c = m^e mod n 인데 message가 홀수라면 결과가 홀수가 나오게 된다.
즉, cipher 만 봐도 message가 홀수인지 짝수인지 알게 된다.
그러므로 Padding 과 Encoding 수행.

OAEP 에서 파라미터에 MGF 알고리즘 등이 들어가므로 잘 확인해봐야한다.

PKCS #5 : Password Based Encryption

  • PBKDF1/PBKDF2 : 패스워드를 통해 대칭키에서 사용가능한 key와 IV를 추출
 - SALT, ITERATION COUNT( 해시 횟수. 표준은 1024~2048인데 지금은 10만번해야...)
  • PBES1/PBES2 : PBKDF1,2 와 대칭키 암호 알고리즘 결합
  • PBMAC1 : 메시지 무결성 확인을 위한 MAC 값 생성 프로세스 설명

PKCS #7 : Cryptographic Message Syntax Standard

다양한 암호메시지를 표현하는 표준 (RFC2630)
  • Data : 일반 OCTET_STRING 데이터 타입
  • Enveloped-Data : 전자봉투 데이터 타입(키 교환정보+암호화된 메시지)
  • Signed-Data : 전자서명 데이터 타입 - 다자간 서명을 지원 함
  • Signed-and-Enveloped-Data : 전자봉투+전자서명 데이터 타입
  • 기타 Useful Type : 인증서, CRL
  • Digested-Data : 메시지 축약 타입
  • Encrypted-Data : 암호화된 메시지 타입
Signed Data - 전자서명 데이터를 담는 포맷
SignedData ::= SEQUENCE {
     version Version,
     digestAlgorithms DigestAlgorithmIdentifiers, - 원본을 Hash 할 알고리즘
     contentInfo ContentInfo, - 원본 데이터
     certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL, - 인증서들
     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, - 인증서 폐기 목록
     signerInfos SignerInfos - 서명자 정보(서명자 ID(발급자정보+시리얼), 추가 의견, 전자 서명
}

SignerInfo - 전자서명 주체에 대한 정보를 담는 포맷 (전자서명 포함)
    
SignerInfo ::= SEQUENCE {
     version Version,
     issuerAndSerialNumber IssuerAndSerialNumber, - 주체 식별자
     digestAlgorithm DigestAlgorithmIdentifier, - 전자서명에 사용할 해시 알고리즘
     authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL, - 전자서명 대상 원문
     digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, - 전자서명 알고리즘
     encryptedDigest EncryptedDigest, - 전자서명 값
     unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL - 기타 정보
}

issuerAndSerialNumber는 주체 식별자로, 
  인증서 목록 중 해당 인증서를 찾는 Key 로 사용된다.
DigestAlgorithm 은 SignedData의 digestAlgorithms 중 하나를 선택.
AuthenticatedAttribute 가 없을 시 SignedData의 contentInfo 를 서명한다.

SignedData 검증 및 거래 처리 (PKCS #7)

거래 요청 전문 과 PKCS #7 SignedData를 따로 전송하기 때문에 
실제 거래 내역과 P7 값이 동일한지 확인을 해야 한다.
예 ) 전문 처리
 s_acct=1002777
 r_acct=2222333
 money=100000
전자서명 데이터(법원)
 입금 계좌=1002777
 출금 계좌=2222333
 입금 금액=10 원

위처럼 거래 전문을 수정하는 공격이 실제로 있어 왔고, 
전자 서명 데이터만 법적인 효력을 지님.
따라서 아래와 같이 검증을 해야 한다.
  1. SignerInfo-Cert 쌍이 거래 요청자와 일치하는지 비교
  2. 전자서명 원문 필드(ContentInfo) Hash
  3. SignerInfo 의 Authenticated Attribute 에 있는 원문 Hash 값과 동일한지 비교
  4. 서명 시간(Signing Time) 이 있을 경우 허용 시간 내 있는지 확인
  5. 서명 검증 (PKCS #1 RSA Verify)
  6. PKCS #7의 ContentInfo 에서 거래 데이터 추출 == 거래 요청 전문인지 확인

PKCS #8 - Private-key Information Syntax Standard

다양한 비대칭키 암호 알고리즘의 개인키를 저장하는 규격을 명시.
파일 형태로 보관되는 개인키의 안전한 보호를 위해 PKCS #5 를 이용해 
패스워드 기반의 암호화 된 형태로 개인키를 보관 가능.

PrivateKeyInfo ::= SEQUENCE {
        version                   Version,
        privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
        privateKey                PrivateKey,
        attributes           [0]  IMPLICIT Attributes OPTIONAL  - vid=Hash(Hash(주민번호|Random))
}
      Version ::= INTEGER
      PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
      PrivateKey ::= OCTET STRING
      Attributes ::= SET OF Attribute


잘못된 Private key Pasword를 입력했는지 어떻게 확인 하는가?

PKCS #5 Padding Remover 의 특성으로 복호화가 되었는지 안되었는지 확인.
  1. 키가 달라도 1/256 확률로 패딩 체크를 넘어감 (끝이 01로 끝나면)
  2. 개인키는 길기 때문에 30 82 가 맞는지. (81 이하일 수 없다.)
30 82 ..... 쓰레기 .... 01 형태가 되면 키가 잘못 되어도 복호화가 된다.
이것은 1/1600만 확률.

PKCS #10 - Certification Request Syntax Standard

인증서 발급 과정에서 사용자가 CA로 전달하는 "인증서 요청서" 에 대한 규격
SubjectDN 과 공개키, 개인키 소유 여부 확인을 위한 서명 정보로 구성되어 있음.

CertificationRequest : 인증서 요청 규격 (SubjectDN + 공개키 + 서명)


PKCS #11 - Cryptographic Token Interface Standard

암호화 장치를 접근하기 위한 C API 규격.
각 암호화 장치를 Slot 으로 구분하고, PIN 번호를 통해 장비에 로그인 한 후 
장비가 제공하는 기능을 사용 할 수 있다.

자바는 JCE 표준을 따른다

PKCS #11 은 모든 상황을 고려해서 설계되어 있지만, 
HSM 모듈/드라이버가 모든 기능을 다 제공 해야 할 의무는 없다.

PKCS #11 Interface - PKCS#11 Driver - HSM

C = AES_CBC_ENC(Key, IV, M) -> 대용량 데이터는 암호화 할 수 없다.

따라서 하기와 같은 식으로 구현되어 있다.
C_Init(Alg, Key, IV)
C_Update(M1)
C_Update(M2)
C_Update(M3)
C_Update(......)
C_Final(M) => C(Padding)

다만 개발자들이 HSM을 먼저 만들고 PKCS #11 을 Wrapping 하도록 만들기 때문에
HSM 성능보다 100% 를 사용 못하는 경우가 많다. 

암호 함수 호출 과정

  1. 드라이버 로드 (libpkcs11.so)
  2. 드라이버 초기화 (Multi-Thread or not)
  3. Slot 리스트 확인
  4. Slot 선택 및 Token 얻기
  5. 세션 열기 (From Token)
  6. 암호 연산 ... 
  7. 세션 닫기

PKCS #12 - Personal Information Exchnage Syntax

사용자 개인정보 (인증서 / 개인키) 등을 안전학 전달 하기 위한 규격.
PKCS #5 와 유사한 PBE 기반의 암호화 방법과 PKCS #7 /#8 규격의 데이터 타입을 지원.

  PFX ::= SEQUENCE {
       version     INTEGER {v3(3)}(v3,...),
       authSafe    ContentInfo, - PKCS #12 규격으로 암호화된 PKCS #7 데이터
       macData     MacData OPTIONAL
   }
-MacData 로 패스워드가 제대로 입력되었는지 확인 할 수 있다. 
PKCS #8 에서 PKCS #5 를 이용하는 것과 달리 단순히 패딩이나 헤더만 보는것이 아니다.
   MacData ::= SEQUENCE {
       mac         DigestInfo,
       macSalt     OCTET STRING,
       iterations  INTEGER DEFAULT 1
       -- Note: The default is for historical reasons and its
       --       use is deprecated.
   }

Local Key ID : 개인키와 인증서 쌍을 확인 할 수 있도록 해 줌.


TSP (Time-Stamp Protocol) 표준

시점 확인 프로토콜( RFC 3161 )
전자 서명 시점을 신뢰된 TSA(Time-Stamp Authority) 가 보증해 줌으로써
전자 문서의 생성 시간을 명확히 확인 (공증) 할 수 있음.
단순히 시간만 증명하는 것이 아니라 이런 문서가 있었다 라는 것을 공증.

원문에 대한 해시값과 시간 정보를 함께 서명한 값 + 시간 정보 





Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
이전 게시물 홈

페이지

  • 홈
  • Hobby

Categories

  • AI
  • AWS
  • Blockchain
  • Hardware
  • Javascript
  • Node.js
  • Plasma
  • Security
  • Study
  • Video
  • android
  • mysql
  • review
  • windows

Popular Posts

  • 회사 프록시와 인증서에 고통받는 그대를 위한 글 (Bash, Gradle, Python, wget, nodejs(npm), apt-get, cURL, git, yarn, androidStudio)
    대기업에 입사하면 장단점이 있는데, 단점 중에 하나가 회사에서 프록시를 사용하여 트래픽 감시를 하므로 프록시 설정을 해주어야 한다는 점 입니다. 특히, 회사에서는 https 트래픽도 감시를 하므로 인증서도 설정해 주어야 합니다. 그런데 문...
  • 블랙보드 강의 녹화 영상 다운로드 가능한 방법 (노설치)
    별도의 설치도 필요 없고 아주 쉽습니다. 구글 크롬브라우저 에서 블랙보드 녹화 영상에  다운로드 가능한 메뉴가 나오게 하는 코드입니다.  먼저 블랙보드 강의자료에 입장하고, 재생 버튼을 클릭 하지 않은 상태로 F12 를 입력합니다. 재생을 클릭하지 마...
  • 태블릿에서 양자내성암호(격자암호) 돌려보기
      Termux에서 양자 내성 암호 돌려보기 많은 시행 착오 끝에 성공 ! 1. Playstore에서 Termux를 설치한다. 2. 양자 내성 암호 라이브러리 빌드를 위한 셋업 pkg update && pkg upgrade -y pkg ...

Blog Archive

  • ▼  2026 (2)
    • ▼  2월 (2)
      • 태블릿에서 양자내성암호(격자암호) 돌려보기
      • 양자컴퓨터와 보안 위협 (쇼어 알고리즘)
  • ►  2025 (3)
    • ►  9월 (1)
    • ►  8월 (1)
    • ►  7월 (1)
  • ►  2024 (2)
    • ►  11월 (2)
  • ►  2023 (2)
    • ►  10월 (1)
    • ►  1월 (1)
  • ►  2022 (10)
    • ►  12월 (1)
    • ►  11월 (3)
    • ►  9월 (1)
    • ►  8월 (1)
    • ►  6월 (2)
    • ►  3월 (2)
  • ►  2021 (9)
    • ►  12월 (3)
    • ►  11월 (1)
    • ►  6월 (1)
    • ►  5월 (2)
    • ►  4월 (2)
  • ►  2020 (12)
    • ►  10월 (1)
    • ►  9월 (2)
    • ►  7월 (1)
    • ►  6월 (1)
    • ►  5월 (5)
    • ►  4월 (1)
    • ►  2월 (1)
  • ►  2019 (14)
    • ►  10월 (2)
    • ►  7월 (1)
    • ►  3월 (4)
    • ►  2월 (2)
    • ►  1월 (5)
  • ►  2018 (14)
    • ►  12월 (2)
    • ►  11월 (4)
    • ►  10월 (1)
    • ►  8월 (2)
    • ►  5월 (4)
    • ►  1월 (1)
  • ►  2017 (12)
    • ►  10월 (2)
    • ►  9월 (9)
    • ►  5월 (1)
  • ►  2016 (8)
    • ►  10월 (2)
    • ►  8월 (1)
    • ►  6월 (1)
    • ►  1월 (4)
  • ►  2015 (6)
    • ►  12월 (3)
    • ►  10월 (1)
    • ►  6월 (1)
    • ►  5월 (1)
  • ►  2014 (10)
    • ►  11월 (1)
    • ►  9월 (1)
    • ►  7월 (1)
    • ►  6월 (1)
    • ►  5월 (3)
    • ►  4월 (1)
    • ►  3월 (2)
  • ►  2013 (28)
    • ►  12월 (3)
    • ►  11월 (6)
    • ►  10월 (6)
    • ►  9월 (6)
    • ►  8월 (1)
    • ►  7월 (3)
    • ►  6월 (3)

구독

글
Atom
글
전체 댓글
Atom
전체 댓글

로드 중입니다...

각오

직접 해보지 않은 것은 포스팅 하지 않겠습니다.

Copyright © 김보안의 블로깅 | Powered by Blogger
Design by Hardeep Asrani | Blogger Theme by NewBloggerThemes.com | Distributed By Gooyaabi Templates