import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "errors" "fmt" "os" "flag" "encoding/hex" "bytes" )
func splitBySize(src []byte, splitSize int) [][]byte { srcSize := len(src)
var arr [][]byte if srcSize <= splitSize { arr = append(arr, src) } else { groups := len(src) / splitSize for i := 0; i < groups; i++ { block := src[:splitSize]
arr = append(arr, block) src = src[splitSize:]
if 0 == len(src) { break }
if len(src) < splitSize { arr = append(arr, src) } } } return arr }
func RsaEncrypt(publicKey []byte, origData []byte) ([]byte, error) { block, _ := pem.Decode(publicKey) if block == nil { return nil, errors.New("decode public key error") } pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, errors.New("parse public key error") } pub := pubInterface.(*rsa.PublicKey) blockSize := (pub.N.BitLen()+7)/8 - 11
blocks := splitBySize(origData, blockSize) buffer := bytes.Buffer{} for _, block := range blocks { encData, err := rsa.EncryptPKCS1v15(rand.Reader, pub, block) if err != nil { return nil, err } buffer.Write(encData) }
return buffer.Bytes(), nil
}
func RsaDecrypt(privateKey []byte, encData []byte) ([]byte, error) { block, _ := pem.Decode(privateKey) if block == nil { return nil, errors.New("private key error!") }
var key interface{} var errParsePK error if block.Type == "RSA PRIVATE KEY" { key, errParsePK = x509.ParsePKCS1PrivateKey(block.Bytes) } else if block.Type == "PRIVATE KEY" { key, errParsePK = x509.ParsePKCS8PrivateKey(block.Bytes) }
if errParsePK != nil { return nil, errParsePK } priv := key.(*rsa.PrivateKey) blockSize := (priv.N.BitLen()) / 8
blocks := splitBySize(encData, blockSize)
buffer := bytes.Buffer{} for _, block := range blocks { encData, err := rsa.DecryptPKCS1v15(rand.Reader, priv, block) if err != nil { return nil, err } buffer.Write(encData) }
return buffer.Bytes(), nil }
var kpub = `-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQ29tNQd8P3RtLuxdSJUUdpVkK WmPzrnkgVT58ENoOseqx3MUKSJhHnPWnbf4nB6+koG3pdw5g1hO4C8mLUQhXNGKu 9P9u5VtdVmSbhX9bfh5sxtAZZnjp4QAQppGwCuso8OkKuPsTCpTb+e69O2XkYlM3 wybBK7bEgfBvV4/4pwIDAQAB -----END PUBLIC KEY-----`
var kpriv = `-----BEGIN RSA PRIVATE KEY----- MIICWwIBAAKBgQDQ29tNQd8P3RtLuxdSJUUdpVkKWmPzrnkgVT58ENoOseqx3MUK SJhHnPWnbf4nB6+koG3pdw5g1hO4C8mLUQhXNGKu9P9u5VtdVmSbhX9bfh5sxtAZ Znjp4QAQppGwCuso8OkKuPsTCpTb+e69O2XkYlM3wybBK7bEgfBvV4/4pwIDAQAB AoGASBzhJ1erEOsi1Y8PiklcB9RjXfO/tw9yuvszy9p1r8U2Z5r2XYqbKX7EQr7z lb5NouXRjV6SFFVWEaHgQL4FxpZcKC7Agq4LcD8y4K2d7lntK33XINSVkfNbF7YO l9AseCEj/3rYef4xuMVyYLcOP1Iu+5WKZEBtiw/GI/0n/kECQQDabkF8aOpsvzOu u3dBt3NPq54kR2m2aH8VFHHWpYSWwwZuPQ68Vj5F/mYyPZsNFqJBS5lkEVDJ7icy X/GgNHh5AkEA9MgkCWRQoHRb204XuVIFgebST8fUhwmCi1TkFSJz9s0JJnGCctjR bybr5spzfEsdBCHBWLnTRktbrZaDMyvyHwJAfzYnPWV84ciZOPJFCijlJ0kz2L0e e/Vvzb8SbYgIKCV84Ub+BgHUUr9OlYP7gSvlY1G8C+NpwbDJczUda8gjQQJAYjk1 jLc+S0Sl33iUuH6bSycOWYk8VPuR8MsdwwVSN0TLWSvPRrqOP+YEX1X5xXR2rkPF TA81Ik32+c8d0pjdzQJAfYYxlPUsrmsMOp9ywpHKfsn64nZGYOqdNmjAbMHu9vrJ WvEW2Y7BmwhVmY10DOIzt0JOA/XTbdQ6UMqEoNVylw== -----END RSA PRIVATE KEY-----`
func doTest(plainMsg string) {
encData, err := RsaEncrypt([]byte(kpub), []byte(plainMsg)) if err != nil { fmt.Println("Error") fmt.Println(err.Error()) } fmt.Println(hex.EncodeToString(encData))
origData, err := RsaDecrypt([]byte(kpriv), encData) if err != nil { fmt.Println("Error") fmt.Println(err.Error()) return }
plainTxt := string(origData) fmt.Println(plainTxt)
if plainMsg != plainTxt{ fmt.Println("encrypt and decrypt Error") }else { fmt.Println("encrypt and decrypt ok") } }
func main() {
plainMsg := flag.String("plainMsg", "", "plain message to encrypt") encMsg := flag.String("encMsg", "", "ecrypted message to decrypt") isEnc := flag.Bool("isEnc", false, "1 is encrypt, 0 is decrypt") flag.Parse()
if *plainMsg == "" && *encMsg == "" { fmt.Println("Error: no param") return }
doTest(*plainMsg)
if *isEnc { encData, err := RsaEncrypt([]byte(kpub), []byte(*plainMsg)) if err != nil { fmt.Println("Error") fmt.Println(err.Error()) } fmt.Println(hex.EncodeToString(encData)) } else { bData, err := hex.DecodeString(*encMsg) if err != nil { fmt.Println("Error") fmt.Println(err.Error()) return } origData, err := RsaDecrypt([]byte(kpriv), bData) if err != nil { fmt.Println("Error") fmt.Println(err.Error()) return } fmt.Println(string(origData)) } }
|