GO语言入门9---AES、DES、RSA算法

目录


AES算法

package main // 固定
import (
    "bytes"
    "fmt"
    "crypto/aes"
    "crypto/cipher"
    "encoding/base32"
)

// 往字符串后面填充0
func ZeroPadding(cipherText []byte, blocksize int) []byte {
    padding := blocksize - len(cipherText) % blocksize
    padText := bytes.Repeat([]byte{0}, padding)
    return append(cipherText, padText...) // 往slice后添加元素
}

// 删除填充数据
func DeleZeroPadding(origData []byte) []byte {
    return bytes.TrimRightFunc(origData, func(r rune) bool {
        return r == rune(0)
    })
}

// 使用加密算法的步骤
// 1、根据密码创建一个cipher
// 2、得到加密块的大小
// 3、按照块的大小把填充原始数据
// 4、用block和key创建加密算法
// 5、用CryptBlocks按照块的大小进行加密
func AesEncrypt(origData, key []byte)([]byte, error) {
    block, err:=aes.NewCipher(key) // 根据key创建密码
    if err != nil {
        return nil, err
    }
    blockSize := block.BlockSize() // 得到加密块的大小
    origData = ZeroPadding(origData, blockSize) // 填充0
    blockMode:=cipher.NewCBCEncrypter(block, key[:blockSize]) // 创建加密算法
    cryped:=make([]byte, len(origData)) // 生成存放加密数据的空间
    blockMode.CryptBlocks(cryped, origData) // 按照块大小加密
    return cryped,nil
}

func AesDecrypt(cryptedData, key []byte)([]byte, error) {
    block, err:=aes.NewCipher(key) // 根据key创建密码
    if err != nil {
        return nil, err
    }
    blockSize := block.BlockSize() // 得到加密块的大小
    blockMode:=cipher.NewCBCDecrypter(block, key[:blockSize]) // 创建解密算法
    origData:=make([]byte, len(cryptedData)) // 创建存放解密串的空间
    blockMode.CryptBlocks(origData, cryptedData) // 解密
    cryptedData=DeleZeroPadding(origData) // 删除填充数据
    return cryptedData, nil
}

func main() { // 大括号的位置是固定的
    ss := "zengraoli"
    // AES128 ,16,24,32,AES128,192,256
    key:=[]byte("1234567891234567")
    // 加密
    ssCryped, aesEncryptErr := AesEncrypt([]byte(ss), key)
    fmt.Println(string(ssCryped), aesEncryptErr)
    // 加密的数据用base64编码
    fmt.Println(base32.StdEncoding.EncodeToString(ssCryped))

    origData, aesDecryptErr := AesDecrypt([]byte(ssCryped), key)
    fmt.Println(string(origData), aesDecryptErr)
}

DES算法

普通版的DES算法

package main // 固定
import (
    "bytes"
    "fmt"
    "crypto/cipher"
    "encoding/base32"
    "crypto/des"
)

// 往字符串后面填充0
func ZeroPadding(cipherText []byte, blocksize int) []byte {
    padding := blocksize - len(cipherText) % blocksize
    padText := bytes.Repeat([]byte{0}, padding)
    return append(cipherText, padText...) // 往slice后添加元素
}

// 删除填充数据
func DeleZeroPadding(origData []byte) []byte {
    return bytes.TrimRightFunc(origData, func(r rune) bool {
        return r == rune(0)
    })
}

// 使用加密算法的步骤
// 1、根据密码创建一个cipher
// 2、得到加密块的大小
// 3、按照块的大小把填充原始数据
// 4、用block和key创建加密算法
// 5、用CryptBlocks按照块的大小进行加密
func DesEncrypt(origData, key []byte)([]byte, error) {
    block, err:=des.NewCipher(key) // 根据key创建密码,和aes不同之处仅仅在这里
    if err != nil {
        return nil, err
    }
    blockSize := block.BlockSize() // 得到加密块的大小
    origData = ZeroPadding(origData, blockSize) // 填充0
    blockMode:=cipher.NewCBCEncrypter(block, key[:blockSize]) // 创建加密算法
    cryped:=make([]byte, len(origData)) // 生成存放加密数据的空间
    blockMode.CryptBlocks(cryped, origData) // 按照块大小加密
    return cryped,nil
}

func DesDecrypt(cryptedData, key []byte)([]byte, error) {
    block, err:=des.NewCipher(key) // 根据key创建密码
    if err != nil {
        return nil, err
    }
    blockSize := block.BlockSize() // 得到加密块的大小
    blockMode:=cipher.NewCBCDecrypter(block, key[:blockSize]) // 创建解密算法
    origData:=make([]byte, len(cryptedData)) // 创建存放解密串的空间
    blockMode.CryptBlocks(origData, cryptedData) // 解密
    cryptedData=DeleZeroPadding(origData) // 删除填充数据
    return cryptedData, nil
}

func main() { // 大括号的位置是固定的
    ss := "zengraoli"
    // DES key的长度为8
    key:=[]byte("12345678")
    // 加密
    ssCryped, aesEncryptErr := DesEncrypt([]byte(ss), key)
    fmt.Println(string(ssCryped), aesEncryptErr)
    // 加密的数据用base64编码
    fmt.Println(base32.StdEncoding.EncodeToString(ssCryped))

    origData, aesDecryptErr := DesDecrypt([]byte(ssCryped), key)
    fmt.Println(string(origData), aesDecryptErr)
}

加强版的DES算法

package main // 固定
import (
    "bytes"
    "fmt"
    "crypto/cipher"
    "encoding/base32"
    "crypto/des"
)

// 往字符串后面填充0
func ZeroPadding(cipherText []byte, blocksize int) []byte {
    padding := blocksize - len(cipherText) % blocksize
    padText := bytes.Repeat([]byte{0}, padding)
    return append(cipherText, padText...) // 往slice后添加元素
}

// 删除填充数据
func DeleZeroPadding(origData []byte) []byte {
    return bytes.TrimRightFunc(origData, func(r rune) bool {
        return r == rune(0)
    })
}

// 使用加密算法的步骤
// 1、根据密码创建一个cipher
// 2、得到加密块的大小
// 3、按照块的大小把填充原始数据
// 4、用block和key创建加密算法
// 5、用CryptBlocks按照块的大小进行加密
func DesEncrypt3(origData, key []byte)([]byte, error) {
    block, err:=des.NewTripleDESCipher(key) // 根据key创建密码,NewTripleDESCipher和普通版本的强度不同
    if err != nil {
        return nil, err
    }
    blockSize := block.BlockSize() // 得到加密块的大小
    origData = ZeroPadding(origData, blockSize) // 填充0
    blockMode:=cipher.NewCBCEncrypter(block, key[:blockSize]) // 创建加密算法
    cryped:=make([]byte, len(origData)) // 生成存放加密数据的空间
    blockMode.CryptBlocks(cryped, origData) // 按照块大小加密
    return cryped,nil
}

func DesDecrypt3(cryptedData, key []byte)([]byte, error) {
    block, err:=des.NewTripleDESCipher(key) // 根据key创建密码
    if err != nil {
        return nil, err
    }
    blockSize := block.BlockSize() // 得到加密块的大小
    blockMode:=cipher.NewCBCDecrypter(block, key[:blockSize]) // 创建解密算法
    origData:=make([]byte, len(cryptedData)) // 创建存放解密串的空间
    blockMode.CryptBlocks(origData, cryptedData) // 解密
    cryptedData=DeleZeroPadding(origData) // 删除填充数据
    return cryptedData, nil
}

func main() { // 大括号的位置是固定的
    ss := "zengraoli"
    // DES3 key的长度为24
    key:=[]byte("123456781234567812345678")
    // 加密
    ssCryped, aesEncryptErr := DesEncrypt3([]byte(ss), key)
    fmt.Println(string(ssCryped), aesEncryptErr)
    // 加密的数据用base64编码
    fmt.Println(base32.StdEncoding.EncodeToString(ssCryped))

    origData, aesDecryptErr := DesDecrypt3([]byte(ssCryped), key)
    fmt.Println(string(origData), aesDecryptErr)
}

RSA算法

RSA依赖于公钥和私钥,所以首先得到两个函数用来生成公钥和私钥

package main // 固定
import (
    "fmt"
    "crypto/rsa"
    "crypto/rand"
    "crypto/x509"
    "encoding/pem"
    "os"
    "flag"
)

// 传入生成key的种子
func GenRsaKey(bits int) error {
     // 传入随机数和种子
    privateKey, err := rsa.GenerateKey(rand.Reader, bits);
    if  err != nil {
        fmt.Println("私钥生成失败")
        return err
    }
    fmt.Println(privateKey)
    derStream:=x509.MarshalPKCS1PrivateKey(privateKey) // 处理privateKey
    block:=&pem.Block{
        Type:"RSA PRIVATE KEY",
        Bytes:derStream,
    }
    privateFile,err:=os.Create("myprivate.pem")
    if  err != nil {
        fmt.Println("私钥生成失败")
        return err
    }
    defer privateFile.Close()
    err = pem.Encode(privateFile, block) // 写入到文件
    if err != nil{
        fmt.Println("私钥生成失败")
        return err
    }

    // 生成公钥
    publicKey:=&privateKey.PublicKey
    fmt.Println(publicKey)//打印公钥
    //derpkix:=x509.MarshalPKCS1PublicKey(publicKey) // MarshalPKCS1PublicKey converts an RSA public key to PKCS#1, ASN.1 DER form.
    derpkix, err:=x509.MarshalPKIXPublicKey(publicKey) // 处理publicKey,MarshalPKIXPublicKey将公钥序列化为 DER 编码的 PKIX 格式。
    if err != nil{
        fmt.Println("公钥生成失败")
        return err
    }
    block=&pem.Block{
        Type:"RSA PUBLIC KEY",
        Bytes:derpkix,
    }
    publicFile, err:=os.Create("mypublic.pem")
    if  err != nil {
        fmt.Println("公钥生成失败")
        return err
    }
    defer publicFile.Close()
    err = pem.Encode(publicFile, block) // 写入到文件
    if err != nil{
        fmt.Println("公钥生成失败")
        return err
    }

    return nil
}

func main() { // 大括号的位置是固定的
    var bits int
    flag.IntVar(&bits, "b", 1024, "密码长度默认为1024")
    if err := GenRsaKey(bits);err != nil {
        fmt.Println("密钥文件生成失败")
    } else {
        fmt.Println("密钥文件生成成功")
    }
}

利用生成出来的公钥和私钥进行数据的加密

package main // 固定
import (
    "fmt"
    "crypto/rsa"
    "crypto/rand"
    "crypto/x509"
    "encoding/pem"
    "os"
    "errors"
    "encoding/base64"
)

var privateKey=[]byte(`
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDImW7UkM5QdNH1WTz1aGZw7uLJsdzQtzw6hWFfzcx1xCDS0u/Y
TRWWaA5cbitBXgFGzG9b8nAslISmKqyfhq+7QU/DykS7Jqy3Y6EsMlToiZhdGXkF
WWTBWZ2hz9gw+oh7H8cwnYjdB+pn0gol1wGFBkuxWqyitJYXSZE0MZXUjwIDAQAB
AoGBAJy6ZEFoMgnie/h5lIsY2pD50+9KLABWaZQ/iejUXh7U8eBGNmaFM4ykGDRX
TyxvSggKyibIsKPkFg/N37lz/e+nkx7eoABxVubm2gis3x5sJIyXzqSqY/EVWyLo
xY6fMk3fVQpRcrzvG9op3yWghM5cB3Mgrk/ZB0w/Rr0szuKBAkEA/iNuVuS8+ySY
55ykFbv4AhVY4OQVmds3mexdrBbzT0pHhyqQnhJ7ORcsdAaNIfxUNRHsGH7wTXwq
l023Gj4JsQJBAMoRmolb4LnDjaCCmqz8tx4VzSS/RVYaOrp944w0UJ+oxJOeHdsK
PRTgLz1UfiF/6B5pHG5ZDQTabFVgPn+TEj8CQEnqGixxqLlOop4yg9LCcdaBSPFX
xSSTiq9c/L2Ri0CTdQxOB/PBok8ve0FfqmqpDgDFbqqNOO0AYQ7Sjp+2TXECQHkL
4JImKtG9Fmsvsa6s2Jk6ICDCP6vbnJC49wW3FRD/jXqMfoAHex21SjcoFULGF2uY
NcLYr5bXrYvbUrUjigsCQQDIE8wU6vZtHFJx8eVWiTbHY4xwn0nLO0D6jrWcZJD4
E485YmBlqectmXhLkV7bPEMolgxlnpCOloxi6xC/zvSk
-----END RSA PRIVATE KEY-----
`)

var publicKey=[]byte(`
-----BEGIN RSA PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDImW7UkM5QdNH1WTz1aGZw7uLJ
sdzQtzw6hWFfzcx1xCDS0u/YTRWWaA5cbitBXgFGzG9b8nAslISmKqyfhq+7QU/D
ykS7Jqy3Y6EsMlToiZhdGXkFWWTBWZ2hz9gw+oh7H8cwnYjdB+pn0gol1wGFBkux
WqyitJYXSZE0MZXUjwIDAQAB
-----END RSA PUBLIC KEY-----
`)

// 传入生成key的种子
func GenRsaKey(bits int) error {
     // 传入随机数和种子
    privateKey, err := rsa.GenerateKey(rand.Reader, bits);
    if  err != nil {
        fmt.Println("私钥生成失败")
        return err
    }
    fmt.Println(privateKey)
    derStream:=x509.MarshalPKCS1PrivateKey(privateKey) // 处理privateKey
    block:=&pem.Block{
        Type:"RSA PRIVATE KEY",
        Bytes:derStream,
    }
    privateFile,err:=os.Create("myprivate.pem")
    if  err != nil {
        fmt.Println("私钥生成失败")
        return err
    }
    defer privateFile.Close()
    err = pem.Encode(privateFile, block) // 写入到文件
    if err != nil{
        fmt.Println("私钥生成失败")
        return err
    }

    // 生成公钥
    publicKey:=&privateKey.PublicKey
    fmt.Println(publicKey)//打印公钥
    //derpkix:=x509.MarshalPKCS1PublicKey(publicKey) // MarshalPKCS1PublicKey converts an RSA public key to PKCS#1, ASN.1 DER form.
    derpkix, err:=x509.MarshalPKIXPublicKey(publicKey) // 处理publicKey,MarshalPKIXPublicKey将公钥序列化为 DER 编码的 PKIX 格式。
    if err != nil{
        fmt.Println("公钥生成失败")
        return err
    }
    block=&pem.Block{
        Type:"RSA PUBLIC KEY",
        Bytes:derpkix,
    }
    publicFile, err:=os.Create("mypublic.pem")
    if  err != nil {
        fmt.Println("公钥生成失败")
        return err
    }
    defer publicFile.Close()
    err = pem.Encode(publicFile, block) // 写入到文件
    if err != nil{
        fmt.Println("公钥生成失败")
        return err
    }

    return nil
}


// 用公钥来加密
func RsaEncrypt(origData []byte)([]byte, error) {
    block, _:=pem.Decode(publicKey)
    if block == nil {
        return nil, errors.New("public key is bad.")
    }
    // 从公钥的bytes中解析得到.PublicKey
    pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
        return nil, err
    }
    pub:=pubInterface.(*rsa.PublicKey)
    return rsa.EncryptPKCS1v15(rand.Reader, pub, origData) // 加密
}

// 用私钥来解密数据
func RsaDecrypt(ciphertext []byte)([]byte, error) {
    block, _:=pem.Decode(privateKey)
    if block == nil {
        return nil, errors.New("private key is bad.")
    }
    // 从私钥的bytes中解析得到.PublicKey
    priInterface, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    if err != nil {
        return nil, err
    }
    return rsa.DecryptPKCS1v15(rand.Reader, priInterface, ciphertext) // 加密
}

func main() { // 大括号的位置是固定的
    //var bits int
    //flag.IntVar(&bits, "b", 1024, "密码长度默认为1024")
    //if err := GenRsaKey(bits);err != nil {
    //  fmt.Println("密钥文件生成失败")
    //} else {
    //  fmt.Println("密钥文件生成成功")
    //}
    ss := "zengraoli"
    var encryptData, decryptData []byte
    var err error
    encryptData, err = RsaEncrypt([]byte(ss))
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("加密后的数据", base64.StdEncoding.EncodeToString(encryptData))

    decryptData, err = RsaDecrypt([]byte(encryptData))
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("解密后的数据", string(decryptData))
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值