개요
HSM(Hardware Security Module)을 사용해 RSA 키를 만들고, 그 키로 메시지를 서명한 다음, 서명값을 검증하는 과정을 Go 언어로 직접 구현해봤습니다.
이번 테스트는 nCipher HSM 환경에서 진행했으며, pkcs11 인터페이스를 통해 아래와 같은 순서로 작업을 수행했습니다:
- HSM에서 RSA 키 생성
- Go 코드로 메시지 서명
- 공개키 추출
- 서명 검증
참고로 HSM은 보안 장비라서 개인키는 외부로 절대 빠져나오지 않고, 공개키만 추출할 수 있습니다.
RSA 키 생성 (HSM 내부)
/opt/nfast/bin/generatekey pkcs11
- 키 label: test2
- 보호방식: module (테스트 용도)
- 알고리즘: RSA, 사이즈: 2048bit
생성 후 HSM 내부적으로 개인키와 공개키가 자동 생성됩니다.
개인키: HSM 내부에 존재, 외부 추출 불가
공개키: pkcs11을 통해 추출 가능
Go로 서명 (sign.go)
// 메시지 파일 읽기
msg, _ := ioutil.ReadFile("message.txt")
// label=test2 개인키 객체 찾기 (PRIVATE_KEY)
template := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_LABEL, "test2"),
pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY),
}
// SHA256 + RSA_PKCS 메커니즘으로 서명 초기화
p.SignInit(session, []*pkcs11.Mechanism{
pkcs11.NewMechanism(pkcs11.CKM_SHA256_RSA_PKCS, nil),
}, privateKey)
// 서명 결과 저장
signature, _ := p.Sign(session, msg)
os.WriteFile("sig_from_go.bin", signature, 0644)
- SignInit에서 SHA256 해시 + RSA 서명을 수행
- 최종 서명 결과는 sig_from_go.bin으로 저장됨
공개키 추출 (export_pub.go)
// label=test2 공개키 객체 찾기 (PUBLIC_KEY)
template := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_LABEL, "test2"),
pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
}
// modulus(N), exponent(E) 추출
pubAttrs := p.GetAttributeValue(session, publicKeyObj, []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_MODULUS, nil),
pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, nil),
})
// RSA 공개키 구조 생성 및 PEM 인코딩
rsa.PublicKey{
N: new(big.Int).SetBytes(modulus),
E: exponent,
}
pem.EncodeToMemory(...) → test_pub.pem 저장
- RSA 공개키는 (modulus, exponent) 만으로 구성됩니다.
서명 검증 (verify.go)
// 공개키 로딩
pub, _ := x509.ParsePKIXPublicKey(decodedPemBytes)
rsaPub := pub.(*rsa.PublicKey)
// 메시지 SHA256 해시
hashed := sha256.Sum256(msg)
// 서명 검증
rsa.VerifyPKCS1v15(rsaPub, crypto.SHA256, hashed[:], signature)
- 서명 검증에 실패하면 "서명 불일치", 성공하면 "위변조 없음" 출력
- sig_from_go.bin은 HSM의 RSA 개인키로 서명된 값이고, 공개키로만 검증 가능
결론
HSM은 키를 안전하게 보관하면서 외부에 노출되지 않도록 서명 작업을 내부에서 처리해주는 장비입니다.
Go 언어와 pkcs11 모듈을 활용하면, 이런 HSM 기반 키 관리와 서명 과정을 코드로 손쉽게 자동화할 수 있습니다.
이번 글에서는 HSM에서 RSA 키를 생성하고, Go로 메시지를 서명한 뒤 공개키를 추출해 서명을 검증하는 전체 흐름을 적어봤습니다.
실제 운영 환경에서는 PIN 인증이나 세션 보안 같은 부분도 함께 신경 써야 한다는 점 참고하세요.
'개발 > Golang' 카테고리의 다른 글
| [go] golang으로 RSA 암복호화 테스트 (2) | 2025.07.27 |
|---|---|
| [go] 월간 인프라 정기점검 리포트 golang 자동화 (0) | 2025.06.04 |

