디지털 서명은 비대칭키를 이용한 증명 방식 중 하나다. 공개키 방식의 비대칭키와는 다르게, 데이터 자체를 암호화 해서 보안을 중요시 여긴다기 보다 데이터를 전송한 사람의 진위를 증명하는데 초점이 맞춰져 있는 방식이다. 디지털 서명 방식에는 비밀키 비대칭키를 사용한다.
디지털 서명이란
아래 글에서는 디지털 서명에 대해 자세하게 다루고 있다. 혹시 개념이 안잡히시는 분들이라면 필독을 추천한다.
우선 디지털 서명을 하기 위해서는 비밀키/공개키 쌍이 필요하다. 원본 데이터를 해시 한 후 자신의 비밀키로 암호화를 진행해야 하기 때문이다.
디지털 서명의 대략적인 플로우는 다음과 같다.
① Holder는 원본 데이터를 SHA256 알고리즘으로 해싱한다.
② hashedData를 자신의 비밀키로 암호화를 한다.
③ 비밀키로 암호화된 데이터를 분산 저장소에 저장한다.
④ Holder는 원본데이터+공개키 정보를 Verifier에게 전달한다.
⑤ Verifier는 원본데이터를 SHA256으로 해싱한 후 분산저장소에서 암호화된 데이터를 가져온다.
⑥ 암호화된 데이터를 공개키로 복호화 환 후 원본을 해싱한 값과 비교한다.
디지털 서명 구현하기 in Node.js
비밀키 방식의 디지털 서명을 구현하기 위해 필요한 모듈은 crypto-js와 secp256k1 알고리즘 모듈이다. secp256k1 알고리즘 모듈에서는 무조건 32 Bytes 길이의 데이터만 비밀키로 암호화가 가능하기 때문에 원본 데이터를 32Bytes 길이의 해시로 변경해줘야 한다. 이 때 crypto-js의 sha256 함수가 필요하다.
① 우선 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)))
'Blockchain' 카테고리의 다른 글
[블록체인 만들기 #1] Block 구성 (Typescript) (0) | 2022.10.09 |
---|---|
블록체인 개발자 기술 면접 준비 질문 정리 (0) | 2022.10.06 |
IPFS Web3.Storage 사용법 (0) | 2022.09.07 |
Truffle migrate Error You must specify a network id in your development configuration in order to use this network (0) | 2022.09.02 |
[Klaytn] Caver-js 사용법 설치 contract call send (0) | 2022.09.01 |
댓글