암호화 관련된 자료들은 워낙 찾아보면 많이 나오는 편이라서;; 근데 또 막상 찾아서 쓸라 하면 또 GPL이고 그래서 짜려니 귀찮고 그런경우가 많다 말이죠 ..
그런이유로 -_-;; 간단히 막 짜서 쓸려고 만든것좀 공유해 봅니다.
//
// Author: PIROGOM
// https://modu-print.tistory.com
// mop.pirogom@gmail.com
// MIT License
//
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"errors"
"io/ioutil"
)
type RSAHelper struct {
PriKey *rsa.PrivateKey
PubKey *rsa.PublicKey
}
/**
* RSA Key 생성
**/
func (r *RSAHelper) GenerateKey(bits int) error {
privateKey, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
r.PriKey = nil
r.PubKey = nil
return err
}
r.PriKey = privateKey
r.PubKey = &privateKey.PublicKey
return nil
}
func (r *RSAHelper) GetPrivate() *rsa.PrivateKey {
return r.PriKey
}
func (r *RSAHelper) GetPublic() *rsa.PublicKey {
return r.PubKey
}
/**
* PrivateToBytePEM
* PrivateToStringPEM
**/
func (r *RSAHelper) PrivateToBytePEM() ([]byte, error) {
if r.PriKey == nil {
return nil, errors.New("private rsa key is nil")
}
privateKeyBytes := x509.MarshalPKCS1PrivateKey(r.PriKey)
privateKeyPEM := pem.EncodeToMemory(
&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: privateKeyBytes,
},
)
return privateKeyPEM, nil
}
func (r *RSAHelper) PrivateToStringPEM() (string, error) {
pemBuf, err := r.PrivateToBytePEM()
if err != nil {
return "", err
}
return string(pemBuf), nil
}
/**
* PrivateFromBytePEM
* PrivateFromFilePEM
**/
func (r *RSAHelper) PrivateFromBytePEM(privateKeyPEM []byte) error {
block, _ := pem.Decode(privateKeyPEM)
if block == nil {
r.PriKey = nil
return errors.New("invalid PEM Block(private key)")
}
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
r.PriKey = nil
return err
}
r.PriKey = privateKey
return nil
}
func (r *RSAHelper) PrivateFromStringPEM(privateKeyPEM string) error {
return r.PrivateFromBytePEM([]byte(privateKeyPEM))
}
func (r *RSAHelper) PrivateFromFilePEM(filename string) error {
fileBuf, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
err = r.PrivateFromBytePEM(fileBuf)
return err
}
/**
* PublicToBytePEM
* PublicToStringPEM
**/
func (r *RSAHelper) PublicToBytePEM() ([]byte, error) {
if r.PubKey == nil {
return nil, errors.New("public rsa key is nil")
}
publicKeyBytes, err := x509.MarshalPKIXPublicKey(r.PubKey)
if err != nil {
return nil, err
}
publicKeyPEM := pem.EncodeToMemory(
&pem.Block{
Type: "RSA PUBLIC KEY",
Bytes: publicKeyBytes,
},
)
return publicKeyPEM, nil
}
func (r *RSAHelper) PublicToStringPEM() (string, error) {
buf, err := r.PublicToBytePEM()
if err != nil {
return "", err
}
return string(buf), nil
}
/**
* PublicFromBytePEM
**/
func (r *RSAHelper) PublicFromBytePEM(publicKeyPEM []byte) error {
block, _ := pem.Decode(publicKeyPEM)
if block == nil {
r.PubKey = nil
return errors.New("invalid PEM Block (public key)")
}
publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
r.PubKey = nil
return err
}
switch pub := publicKey.(type) {
case *rsa.PublicKey:
r.PubKey = pub
return nil
default:
return errors.New("invalid key type")
}
}
func (r *RSAHelper) PublicFromStringPEM(publicKeyPEM []byte) error {
return r.PublicFromBytePEM([]byte(publicKeyPEM))
}
func (r *RSAHelper) PublicFromFilePEM(filename string) error {
fileBuf, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
err = r.PublicFromBytePEM(fileBuf)
return err
}
/**
* EncryptByte
**/
func (r *RSAHelper) EncryptByte(src []byte) ([]byte, error) {
if r.PubKey == nil {
return nil, errors.New("public key is nil")
}
ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, r.PubKey, src)
if err != nil {
return nil, err
}
return ciphertext, nil
}
func (r *RSAHelper) EncryptString(src string) (string, error) {
enc, err := r.EncryptByte([]byte(src))
if err != nil {
return "", err
}
return hex.EncodeToString(enc), nil
}
/**
* DecryptByte
**/
func (r *RSAHelper) DecryptByte(src []byte) ([]byte, error) {
if r.PriKey == nil {
return nil, errors.New("private key is nil")
}
plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, r.PriKey, src)
if err != nil {
return nil, err
}
return plaintext, nil
}
func (r *RSAHelper) DecryptString(src string) (string, error) {
bsrc, err := hex.DecodeString(src)
if err != nil {
return "", err
}
dec, err := r.DecryptByte(bsrc)
if err != nil {
return "", err
}
return string(dec), nil
}
RSAHelper 라는 구조체와 그 구조체에 딸린 메소드들입니다.
package main
import "fmt"
func main() {
rh := RSAHelper{}
rh.GenerateKey(1024)
priv_pem, _ := rh.PrivateToStringPEM()
pub_pem, _ := rh.PublicToStringPEM()
fmt.Println(priv_pem)
fmt.Println(pub_pem)
s := "PIROGOM|hahahaha|panichwanja|20220303"
fmt.Println("plain", s)
enc, _ := rh.EncryptString(s)
fmt.Println(enc)
dec, _ := rh.DecryptString(enc)
fmt.Println(dec)
}
이런식으로 쓰시면 되겠습니다. 예제에선 오류체크를 전혀 안하고 있는데 .. 별로 좋은 습관은 아닌거 아시죠? ㅋㅋ 뭔가 잘 안될떈 _ 로 무시중인 error 리턴 값들을 확인 바랍니다.
GenerateKey 함수의 인자는 몇비트로 키를 만들꺼냐의 문제인데 값이 크면 클수록 키 생성과 암호화, 복호화에 시간이 많이 소요됩니다.
나머지는 그리 어려운 구조의 코드는 아니니까 ;;
필요하면 가따 쓰소서~
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] ed25519 암호화/복호화/서명/검증 알고리즘 (0) | 2022.03.11 |
[Go언어/GUI] WebView 로딩 문제 .. (0) | 2022.02.22 |
[Go언어/GUI] WebView이용시 자바스크립트 오류 문제 (0) | 2022.02.18 |
Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #13 (0) | 2022.02.16 |
Go로 MS 윈도 네이티브 GUI 프로그램 만들기 #12 (0) | 2022.02.16 |