본문 바로가기
Blockchain

[Node.js] 디지털 서명 SHA256 32Bytes 비대칭키 사용방법

by 개발자 염상진 2022. 9. 15.

디지털 서명은 비대칭키를 이용한 증명 방식 중 하나다. 공개키 방식의 비대칭키와는 다르게, 데이터 자체를 암호화 해서 보안을 중요시 여긴다기 보다 데이터를 전송한 사람의 진위를 증명하는데 초점이 맞춰져 있는 방식이다. 디지털 서명 방식에는 비밀키 비대칭키를 사용한다.

 

 

디지털 서명이란

 

아래 글에서는 디지털 서명에 대해 자세하게 다루고 있다. 혹시 개념이 안잡히시는 분들이라면 필독을 추천한다.

 

 

우선 디지털 서명을 하기 위해서는 비밀키/공개키 쌍이 필요하다. 원본 데이터를 해시 한 후 자신의 비밀키로 암호화를 진행해야 하기 때문이다. 

 

[Security] 디지털 서명(Digital Signature)이란? 검증 확인 원리

공개 키 방식(PKC, Public Key Cryptographym)은 전형적인 비대칭키 암호 방식을 사용합니다. 공개키와 개인키로 구성된 두개의 키로 암호화/복호화를 진행합니다. 공개키와 개인키는 ECDSA라는 타원 곡선

about-tech.tistory.com

 

디지털 서명의 대략적인 플로우는 다음과 같다. 

① Holder는 원본 데이터를 SHA256 알고리즘으로 해싱한다. 

② hashedData를 자신의 비밀키로 암호화를 한다.

③ 비밀키로 암호화된 데이터를 분산 저장소에 저장한다.

④ Holder는 원본데이터+공개키 정보를 Verifier에게 전달한다.

⑤ Verifier는 원본데이터를 SHA256으로 해싱한 후 분산저장소에서 암호화된 데이터를 가져온다.

⑥ 암호화된 데이터를 공개키로 복호화 환 후 원본을 해싱한 값과 비교한다. 

 

디지털 서명 방식

 

 

디지털 서명 구현하기 in Node.js

 

비밀키 방식의 디지털 서명을 구현하기 위해 필요한 모듈은 crypto-jssecp256k1 알고리즘 모듈이다. secp256k1 알고리즘 모듈에서는 무조건 32 Bytes 길이의 데이터만 비밀키로 암호화가 가능하기 때문에 원본 데이터를 32Bytes 길이의 해시로 변경해줘야 한다. 이 때 crypto-js의 sha256 함수가 필요하다.

 

 

 

 

 

secp256k1

This module provides native bindings to ecdsa secp256k1 functions. Latest version: 4.0.3, last published: 8 months ago. Start using secp256k1 in your project by running `npm i secp256k1`. There are 1270 other projects in the npm registry using secp256k1.

www.npmjs.com

 

 

crypto-js

JavaScript library of crypto standards.. Latest version: 4.1.1, last published: a year ago. Start using crypto-js in your project by running `npm i crypto-js`. There are 8123 other projects in the npm registry using crypto-js.

www.npmjs.com

 

 

① 우선 2가지 모듈을 import 한다.

const { randomBytes } = require('crypto')
const secp256k1 = require('secp256k1')

 

② 비밀키/공개키를 생성한다. 공개키는 비밀키를 조합해서 생성한다. secp256k1은 ECDH 알고리즘을 사용해 키 페어를 생성한다.

function getPrivateKey () {
    while (true) {
      const privKey = randomBytes(32)
      if (secp256k1.privateKeyVerify(privKey)) return privKey
    }
  }

const privKey=getPrivateKey();

const pubKey = secp256k1.publicKeyCreate(privKey)

 

 

 

③ 원본데이터를 SHA256 함수로 해싱한다.

let hash   = CryptoJS.SHA256(JSON.stringify("원본데이터")).toString(CryptoJS.enc.Hex);

 

④ 해싱 데이터를 비밀키로 암호화 한다.(디지털 서명)

const sigObj = secp256k1.ecdsaSign(Buffer.from(hash, 'hex'), privKey)

 

⑤ 암호문을 공개키로 복호화한다.(디지털 서명 검증) 결과값은 true/false 값으로 출력된다.

const result = secp256k1.ecdsaVerify(
    sigObj.signature,
    Buffer.from(
      CryptoJS.SHA256(JSON.stringify("검증할 원본데이터")).toString(CryptoJS.enc.Hex),
      "hex"
    ),
    pubKey
  )

 

 

만약 생성된 Key Pairs를 DB에 담은 후 가져오기 위해서는 JSON.stringify / JSON.parse() 를 이용한다. pubKey의 경우 Uint8Array 형식의 데이터이므로, JSON.parse()를 해줄 때 형식을 맞춰 변환해줘야 한다.

// 문자열 변환
const DBprivKey = JSON.stringify(privKey) 
const DBpubKey = JSON.stringify(pubKey)

// JSON.parse()
const newPrivKey = Buffer.from(JSON.parse(DBprivKey))
const newPubKey  = new Uint8Array(Object.values(JSON.parse(DBpubKey)))

 

 

 

Node.js crypto 비대칭키 대칭키 구현하기

암호화는 프로그램에서 굉장히 중요한 분야고 계속해서 연구가 진행되고 있습니다. 많은 연구자들이 좀더 안전한 암호화 알고리즘을 개발하고 있고, 현재 우리는 알게 모르게 그들의 결과물을

about-tech.tistory.com

 

 

[Blockchain] 스마트 컨트랙트 월렛(Contract Account)?

이더리움 블록체인에서 일반적으로는 EOA(External Owned Account)를 통해 자산을 관리할 수 있습니다. 하지만 EOA는 제한된 기능을 가지고 있습니다. 대표적으로 스마트 컨트랙트 코드를 담을 수 없습

about-tech.tistory.com

 

 

[Blockchain] 채굴(Mining)이란?

블록체인에서 채굴(Mining)이란 블록체인 네트워크 상에서 발생하는 트랜잭션들을 검증하고, 분산원장에 기록하는 행위를 통해 보상으로 암호화폐를 얻는 과정입니다. 땅에 묻혀 있는 광물을 캐

about-tech.tistory.com

 

댓글