본문 바로가기
개발 및 알고리즘/알고리즘

Public Key로 암호화된 Private Key Signature 검증하기 (jsrsasign)

by 0xseo 2024. 8. 17.
반응형

이전 글(리액트 네이티브에서 지문 인식 구현하기)에서 지문 인식을 도입한 프로젝트는 서버가 없어 react native단에서 직접 pulbic key를 안전하게 저장해놨다가, signature를 받아 검증까지 해야 했다.


이를 위해서 모듈 react-native-keychain과 jsrsasign을 사용하였다.
여기서는 jsrsasign와 Buffer을 이용해 검증하는 과정을 기록한다.

우선 필자는 서버를 잘 모른다. 백엔드 다뤄본 것이라고는 데이터베이스밖에 없는 것이다.
그래서 많이 헤매었다...

 

필요한 모듈을 다운받자.

npm i jsrsasign --save
cd iOS
pod install
Buffer는 다운받지 않아도 된다.

 

 

react-native-biometrics에서 createSignature 함수를 이용해 생성한 signature를 검증하기 위해서는 public key가 필요하다.

[React Native] 리액트 네이티브에서 keychain store 구현하기 (react-native-keychain)

const publicKey = await keyStore.getItem('bioPubKey')

 

 

가져온 publicKey는 base64로 encoded key이지만 PEM 형식은 아니다.
PEM 형식이라면 앞뒤에 -----BEGIN PUBLIC KEY-----\n 이런 문자열이 필요하다고 한다. 붙여주자.

const pemFormattedPublicKey `= -----BEGIN PUBLIC KEY-----\n${publicKey}\n-----END PUBLIC KEY-----`

 

 

signature을 검증하기 위해서 KJUR의 Signature 객체를 가져오자. 알고리즘은 react-native-biometrics에 나와 있듯 SHA256withRSA이다.

const sig = new KJUR.crypto.Signature({ alg: 'SHA256withRSA' })

 

 

PEM 형식으로 바꾼 public key로 init해주고, react-native-biometrics에서 해주었듯 payload (여기서는 userID)로 update해준다.

sig.init(pemFormattedPublicKey)
sig.updateString(payload)

 

 

마지막으로 signature를 검증해주기만 하면 된다. public key와 마찬가지로 base64 encoded 상태이기 때문에 hex 형태로 바꿔준다. 이때 Buffer를 이용한다.

const buffer = Buffer.from(signature, 'base64')
const bufString = buffer.toString('hex')

 

 

hex 형식으로 바꿔준 signature를 아까 생성한 Signature 객체로 검증한다.

const isValid = sig.verify(bufString)

 

 

(전문)

import { KJUR } from 'jsrsasign'
import { Buffer } from 'buffer'

export async function verifySignature( publicKey: string, signature: string, payload: string ) {
  try {
    // verify signature with public key
    const pemFormattedPublicKey = `-----BEGIN PUBLIC KEY-----\n${publicKey}\n-----END PUBLIC KEY-----`
    const sig = new KJUR.crypto.Signature({ alg: 'SHA256withRSA' })

    sig.init(pemFormattedPublicKey)
    sig.updateString(payload)

    const buffer = Buffer.from(signature, 'base64')
    const bufString = buffer.toString('hex')

    const isValid = sig.verify(bufString)

    return isValid
  } catch (error) {
    console.error('Error verifying signature:', error)
    return false
  }
}
반응형