Golang RSA 加密解密

yufei       1 月, 3 周 前       142

  1. 首先创建一个 RSA 密钥,我们使用的是 2048,你可以使用 1024 或者 4096

    但数字越大,加密后的数据也越大,耗时也越长

    openssl genrsa -out private.pem 2048
    
  2. 然后根据密钥创建公钥

    openssl rsa -in private.pem -pubout -out public.pem
    

编写测试代码

package main

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/sha1"
    "crypto/x509"
    "encoding/base64"
    "encoding/pem"
    "fmt"
)

func private_key() []byte {
    return []byte(`
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAzuYg4WLstsyB9yyEQ4r5G6HF2TncncEirrM+aQQfk2VFm+HG
9gZiqW8BZIuKcJ2yMfNn2pefsiFf56pijqafsxEUb9V+9xy3TBx51eqiQJE7DIOj
8iFBSQHMLsPR//3qFXlAZyysg0b+nnZ+/72P1OVljOYBs03JT4OkgPFbm3W6+T9B
TVEvW4SwmS0Tbw+1AYCBg60AiY2Y5/HeVnEtSPOsg8kKo4RukeKakHGAzpmnrlV4
uvWV7gGX4zB4XzCFXEylyAPwFZyBEsdiPwlqhIkiMth0rmgzb8ee6RQBbw3iltU0
e67ra+hinxMqdLIZ5uE1NsrbPXB2G4I6SP8V4QIDAQABAoIBAAE39cWeEYraFYHh
Lz4+mU0CXOn0n0oGky+4OovfzFfP5uMOJ1/XlcktsDJpZ/1V0HDe4CO3dOdVrvzs
UfxJGvOxDA/EkCTgdGvsVwNdiGsc794ZAGQysfG+Ive7i4cYdcJ+nlR9PN7hEirY
w9K5yRkV6M01pZjqwl7HhbaEtWdq/WEnjcQc9tWTcUh754NWCT8ukMdned/mx/f/
fZZMdlnO9ocR3OAW6aND+Zcw71Ui4QPKx5r8TEp1svBn2yuptxOHlcP6xeocU7av
PhgOTDB1D0YiAlJlYI6YeRg66Lrm3OKi2xlFUDfOA+a7qF9auJLsyDzGTt751aGS
3m5sGgECgYEA9xOc6ZPsPNtipy6/aNpuncodFCDQspDOPzwAzhge6w7LuDt20yev
546lN3YvE91dbZQ+HVG+/Uv6SRuDCsU5n0IjruoNvAz+D4q7GZu6+SgBeuXgEECk
D255eCi9aXpsiEgIM/9LOkKP1e7eEqdMTKDORN3a0Xh8exMp0bZaMdECgYEA1l8L
2Ju6iVrPOorNK79ftZRc0jbrX6DEvfaUfSZptB7BmLzJoaEcVdEXre93Ip2Hu6WA
i1Fm09HJXU0edI1wcI0e0gQSIOCqf3OEeNrBreBYFJpg4NgUa6Zs3VTlNezxFFbu
Vp6aah6UbwK8+0a0G8SC6gJbtq3vmUUHfkQIFxECgYB9l1GehZuCv72g36laQhYS
TOeFEL0k12iPSg/asvYcY7P4HPnkkXrfyGmBDKkXfuF7zuvX+XKMzK8XtE1jDyeg
JX1/7uc2XKBUBB/g/4EGH2jJMMo5WLJMScqi4oqNcDZ0+7B3xeBWZ/k3NKlbcADf
vqm65c7RxV35LZ+HQxsL0QKBgQDG0VP9S0FQDsbPdtge0NkFYVpNJN5bzJFr1XuW
LsAua7AF5mHi47eR5+DcUpHdqtiuMirsC00g+xqUy+eJFXzJBjklct0VXQkEN7EP
HWQvzTgjs6JSJlWaGbox9IC46M4WnSFjeKmh7kagRpvbOJHmhvUb75/754mmTx1J
//K44QKBgQCsQmsd5dnYLTfT6a8yQ0y0evWMlpBLkBwMSOhR9CYi9OrJZGkvuuz2
7gKXkL1oWPUoFZ6C3V/4hU9mt3lo/3D7LCqVrau9W3LQZlY7x/hbR8suoSjWmoxo
Q8n9IBNXoVGzFu4t/eQg5wTIm9aSO+uWBXKPYMmyXbItfiPfiX6UOA==
-----END RSA PRIVATE KEY-----
`)
}

func public_key() []byte {
    return []byte(`
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzuYg4WLstsyB9yyEQ4r5
G6HF2TncncEirrM+aQQfk2VFm+HG9gZiqW8BZIuKcJ2yMfNn2pefsiFf56pijqaf
sxEUb9V+9xy3TBx51eqiQJE7DIOj8iFBSQHMLsPR//3qFXlAZyysg0b+nnZ+/72P
1OVljOYBs03JT4OkgPFbm3W6+T9BTVEvW4SwmS0Tbw+1AYCBg60AiY2Y5/HeVnEt
SPOsg8kKo4RukeKakHGAzpmnrlV4uvWV7gGX4zB4XzCFXEylyAPwFZyBEsdiPwlq
hIkiMth0rmgzb8ee6RQBbw3iltU0e67ra+hinxMqdLIZ5uE1NsrbPXB2G4I6SP8V
4QIDAQAB
-----END PUBLIC KEY-----
`)
}

func EncryptOAEP(text string) (string, error) {
    rsaPublicKey, err := ParsePKIXPublicKey()
    if err != nil {
        return "", err
    }
    secretMessage := []byte(text)
    rng := rand.Reader
    cipherdata, err := rsa.EncryptOAEP(sha1.New(), rng, rsaPublicKey, secretMessage, nil)
    if err != nil {
        return "", nil
    }
    ciphertext := base64.StdEncoding.EncodeToString(cipherdata)
    return ciphertext, nil
}

// 解密
func DecryptOAEP(ciphertext string) (string, error) {
    rsaPrivateKey, err := ParsePKCS1PrivateKey()
    if err != nil {
        return "", err
    }

    cipherdata, _ := base64.StdEncoding.DecodeString(ciphertext)
    rng := rand.Reader
    plaintext, err := rsa.DecryptOAEP(sha1.New(), rng, rsaPrivateKey, cipherdata, nil)
    if err != nil {
        return "", nil
    }

    return string(plaintext), nil
}

func ParsePKIXPublicKey() (*rsa.PublicKey, error) {
    block, _ := pem.Decode(public_key())
    pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
        return nil, err
    }
    return pubInterface.(*rsa.PublicKey), nil
}

func ParsePKCS1PrivateKey() (*rsa.PrivateKey, error) {
    block, _ := pem.Decode(private_key())
    privateInterface, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    if err != nil {
        return nil, err
    }
    return privateInterface, nil
}

func main() {

    ciphertext, err := EncryptOAEP("www.twle.cn")
    if err != nil {
        panic(err)
    }
    fmt.Printf("Ciphertext: \n%x\n", ciphertext)
    plaintext, err := DecryptOAEP(ciphertext)
    if err != nil {
        panic(err)
    }
    fmt.Printf("\nPlaintext: \n%s\n", string(plaintext))
}

运行结果如下

Ciphertext: 
4569586277744f623530596366503543546a34314f58705244794c6141353478526b49724b725852433745366246666631332f4e414c7a526968746855334a666648592b785a612b33514f305645784c2f7045774c6e343052657349376a324a6b73466f6e5235424c376976632f4439375449674b672f676f6142387a4f63466b526536324136446d54356a452b51566d7154722f442b3546786f757645647050774f663461654e305163374d72344d384d366677625063412f63716a48355541573732586771345931646a4b4436333059667468464b566f4637523341674b572b5555416f6739712f4c3167795533534f69324c74366a4e4c2b77476d78712b72493651635346424b4c616b585a303344466d30724838397138474e6448514d79464473714f745647524351306f65445759484c5332446d67314361526f3268346b596a41554449544341794d35646e4d635775673d3d

Plaintext: 
www.twle.cn
目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2018 简单教程 twle.cn All Rights Reserved.