특정 데이터의 유효성 검증을 위해서 만든 메소드들입니다. 원래 ECDSA 를 사용하는 놈으로 만들었다가 키를 만드는데 사용되는 P256.. 등의 P시리즈 커브들이 이래저래 말들이 많아서 ED25519를 사용하는 방식으로 변경하였습니다.
ED25519 나 ECDSA는 데이터를 암호화하고 복호화하는데 사용되는게 아니라 특정 데이터에 개인키로 서명(Sign)을 하고 공개키로 서명이 유효한지를 검증해주는 방식으로 사용합니다.
예를들어 데이터가 "피로곰"인 경우에 서버에서 "피로곰"에 개인키로 서명을하고 서명되고 암호화된 데이터를 클라이언트에 전송하면 클라이언트에서는 "피로곰"과 서버에서 보내준 서명된 데이터를 가지고 공개키로 검증을 합니다.
애초에 사인하기 전의 원본 데이터를 모르거나 원본데이터를 알아도 서명이 검증되지 못하면 문제 있는 데이터가 되버리는 것이지요..
내가 알고 있는 이 값이 .. 정말 상대가 보낸 값이 맞는가를 검증하는데 사용하시면 되겠습니다.
//
// Author: PIROGOM
// https://modu-print.tistory.com
// mop.pirogom@gmail.com
// MIT License
//
package main
import (
"crypto/ed25519"
"crypto/rand"
"crypto/sha256"
"encoding/hex"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
)
type ECDSAHelper struct {
PrivateKey *ed25519.PrivateKey
PublicKey *ed25519.PublicKey
}
/**
* Generate
**/
func (e *ECDSAHelper) Generate() error {
if e.PrivateKey != nil {
e.PrivateKey = nil
e.PublicKey = nil
}
publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return err
}
e.PrivateKey = &privateKey
e.PublicKey = &publicKey
return nil
}
/**
* EncodePrivateKey
**/
func (e *ECDSAHelper) EncodePrivateKey() ([]byte, error) {
if e.PrivateKey == nil {
return nil, errors.New("private key is nil")
}
encBuf := pem.EncodeToMemory(
&pem.Block{
Type: "ED25519 PRIVATE KEY",
Bytes: *e.PrivateKey,
})
return encBuf, nil
}
/**
* DecodePrivateKey
**/
func (e *ECDSAHelper) DecodePrivateKey(encKey []byte) error {
if e.PrivateKey != nil {
e.PrivateKey = nil
}
block, _ := pem.Decode(encKey)
if block == nil {
return errors.New("failed to find ED25519 PRIVATE KEY")
}
if block.Type != "ED25519 PRIVATE KEY" {
return fmt.Errorf("%s is invalid block type", block.Type)
}
e.PrivateKey = (*ed25519.PrivateKey)(&block.Bytes)
return nil
}
/**
* PrivateKeyToFile
**/
func (e *ECDSAHelper) PrivateKeyToFile(fname string) error {
if e.PrivateKey == nil {
return errors.New("private key is nil")
}
enc, err := e.EncodePrivateKey()
if err != nil {
return err
}
err = ioutil.WriteFile(fname, enc, 0644)
if err != nil {
return err
}
return nil
}
/**
* PrivateKeyFromFile
**/
func (e *ECDSAHelper) PrivateKeyFromFile(fname string) error {
if e.PrivateKey != nil {
e.PrivateKey = nil
}
buf, err := ioutil.ReadFile(fname)
if err != nil {
return err
}
err = e.DecodePrivateKey(buf)
if err != nil {
return err
}
return nil
}
/**
* EncodePublicKey
**/
func (e *ECDSAHelper) EncodePublicKey() ([]byte, error) {
if e.PublicKey == nil {
return nil, errors.New("public key is nil")
}
encBuf := pem.EncodeToMemory(
&pem.Block{
Type: "ED25519 PUBLIC KEY",
Bytes: *e.PublicKey,
})
return encBuf, nil
}
/**
* DecodePublicKey
**/
func (e *ECDSAHelper) DecodePublicKey(encKey []byte) error {
if e.PublicKey != nil {
e.PublicKey = nil
}
block, _ := pem.Decode(encKey)
if block == nil {
return errors.New("failed to find ED25519 PUBLIC KEY")
}
if block.Type != "ED25519 PUBLIC KEY" {
return fmt.Errorf("%s is invalid block type", block.Type)
}
e.PublicKey = (*ed25519.PublicKey)(&block.Bytes)
return nil
}
/**
* PublicKeyToFile
**/
func (e *ECDSAHelper) PublicKeyToFile(fname string) error {
if e.PublicKey == nil {
return errors.New("public key is nil")
}
enc, err := e.EncodePublicKey()
if err != nil {
return err
}
err = ioutil.WriteFile(fname, enc, 0644)
if err != nil {
return err
}
return nil
}
/**
* PublicKeyFromFile
**/
func (e *ECDSAHelper) PublicKeyFromFile(fname string) error {
if e.PublicKey != nil {
e.PrivateKey = nil
}
buf, err := ioutil.ReadFile(fname)
if err != nil {
return err
}
err = e.DecodePublicKey(buf)
if err != nil {
return err
}
return nil
}
/**
* Sign
**/
func (e *ECDSAHelper) Sign(msg string) ([]byte, error) {
if e.PrivateKey == nil {
return nil, errors.New("private key is nil")
}
hash := sha256.Sum256([]byte(msg))
signed := ed25519.Sign(*e.PrivateKey, hash[:])
return signed, nil
}
/**
* SignToString
**/
func (e *ECDSAHelper) SignToString(msg string) (string, error) {
signed, err := e.Sign(msg)
if err != nil {
return "", err
}
return hex.EncodeToString(signed), nil
}
/**
* SignToPEM
**/
func (e *ECDSAHelper) SignToPEM(msg string, blockType string) ([]byte, error) {
signed, err := e.Sign(msg)
if err != nil {
return nil, err
}
encBuf := pem.EncodeToMemory(
&pem.Block{
Type: blockType,
Bytes: signed,
})
return encBuf, nil
}
/**
* SignFromPEM
**/
func (e *ECDSAHelper) SignFromPEM(pemBuf []byte, blockType string) ([]byte, error) {
block, _ := pem.Decode(pemBuf)
if block == nil {
return nil, errors.New("failed to find ED25519 PUBLIC KEY")
}
if block.Type != blockType {
return nil, fmt.Errorf("%s is invalid block type", block.Type)
}
return block.Bytes, nil
}
/**
* IsValidSignPEM
**/
func (e *ECDSAHelper) IsValidSignPEM(pemBuf []byte, blockType string) bool {
block, _ := pem.Decode(pemBuf)
if block == nil {
return false
}
if block.Type != blockType {
return false
}
return true
}
/**
* Verify
**/
func (e *ECDSAHelper) Verify(msg string, signed []byte) bool {
if e.PublicKey == nil {
return false
}
hash := sha256.Sum256([]byte(msg))
return ed25519.Verify(*e.PublicKey, hash[:], signed)
}
/**
* VerifyString
**/
func (e *ECDSAHelper) VerifyString(msg string, signed string) bool {
byteSigned, err := hex.DecodeString(signed)
if err != nil {
return false
}
return e.Verify(msg, byteSigned)
}
Go언어 ORM 무엇을 써야 하나? (0) | 2022.07.06 |
---|---|
Go 백엔드 프레임워크 - Echo,Gin vs Fiber (0) | 2022.06.22 |
[Go언어/윈도GUI] 파일 드래그앤드랍(Drag&Drop) 처리 (0) | 2022.03.23 |
Go언어 윈도 GUI 개발관련 win/walk 패키지 분리 (0) | 2022.03.23 |
[Go언어/GOLANG] RSA 암호화/복호화 (0) | 2022.03.04 |
[Go언어/GUI] WebView 로딩 문제 .. (0) | 2022.02.22 |
[Go언어/GUI] WebView이용시 자바스크립트 오류 문제 (0) | 2022.02.18 |
Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #13 (0) | 2022.02.16 |