前言

Golang比较强大,之前笔者在研究区块链的时间总结过加解密,这篇博文里的代码在其基础上进行了整理。笔者下面提供的代码是经过多语言环境验证,可以与其他语言互通。

  1. C#、Golang、Python、Java(Android)之间Des、Rsa加解密互通系列之前言
  2. C#、Golang、Python、Java(Android)之间Des、Rsa加解密互通系列之C#
  3. C#、Golang、Python、Java(Android)之间Des、Rsa加解密互通系列之Golang
  4. C#、Golang、Python、Java(Android)之间Des、Rsa加解密互通系列之Python
  5. C#、Golang、Python、Java(Android)之间Des、Rsa加解密互通系列之Java(Android)

代码

Des对称加密工具类

package sddesimport ("bytes""crypto/cipher""crypto/des")func Encrypt(origData, key []byte, iv []byte) ([]byte, error) {block, err := des.NewCipher(key)if err != nil {return nil, err}origData = PKCS5Padding(origData, block.BlockSize())// origData = ZeroPadding(origData, block.BlockSize())blockMode := cipher.NewCBCEncrypter(block, iv)crypted := make([]byte, len(origData))// 根据CryptBlocks方法的说明,如下方式初始化crypted也可以// crypted := origDatablockMode.CryptBlocks(crypted, origData)return crypted, nil}func Decrypt(crypted, key []byte, iv []byte) ([]byte, error) {block, err := des.NewCipher(key)if err != nil {return nil, err}blockMode := cipher.NewCBCDecrypter(block, iv)origData := make([]byte, len(crypted))// origData := cryptedblockMode.CryptBlocks(origData, crypted)origData = PKCS5UnPadding(origData)// origData = ZeroUnPadding(origData)return origData, nil}// 3DES加密func TripleEncrypt(origData, key []byte, iv []byte) ([]byte, error) {block, err := des.NewTripleDESCipher(key)if err != nil {return nil, err}origData = PKCS5Padding(origData, block.BlockSize())blockMode := cipher.NewCBCEncrypter(block, iv)crypted := make([]byte, len(origData))blockMode.CryptBlocks(crypted, origData)return crypted, nil}// 3DES解密func TripleDecrypt(crypted, key []byte, iv []byte) ([]byte, error) {block, err := des.NewTripleDESCipher(key)if err != nil {return nil, err}blockMode := cipher.NewCBCDecrypter(block, iv)origData := make([]byte, len(crypted))blockMode.CryptBlocks(origData, crypted)origData = PKCS5UnPadding(origData)return origData, nil}func ZeroPadding(ciphertext []byte, blockSize int) []byte {padding := blockSize - len(ciphertext)%blockSizepadtext := bytes.Repeat([]byte{0}, padding)return append(ciphertext, padtext...)}func ZeroUnPadding(origData []byte) []byte {return bytes.TrimRightFunc(origData, func(r rune) bool {return r == rune(0)})}func PKCS5Padding(ciphertext []byte, blockSize int) []byte {padding := blockSize - len(ciphertext)%blockSizepadtext := bytes.Repeat([]byte{byte(padding)}, padding)return append(ciphertext, padtext...)}func PKCS5UnPadding(origData []byte) []byte {length := len(origData)unpadding := int(origData[length-1])return origData[:(length - unpadding)]}

Rsa密钥对生成工具类

//生成公钥和私钥 pem文件package mainimport ("crypto/rand""crypto/rsa""crypto/x509""encoding/asn1""encoding/pem""flag""log""os")func main() {var bits intflag.IntVar(&bits, "b", 1024, "秘钥长度,默认为1024")if err := GenRsaKey(bits); err != nil {log.Fatal("秘钥文件生成失败")}log.Println("秘钥文件生成成功")}//生成 PKCS1私钥、PKCS8私钥和公钥文件func GenRsaKey(bits int) error {//生成私钥文件privateKey, err := rsa.GenerateKey(rand.Reader, bits)if err != nil {return err}derStream := x509.MarshalPKCS1PrivateKey(privateKey)block := &pem.Block{Type:  "RSA PRIVATE KEY",Bytes: derStream,}file, err := os.Create("private_key.pem")if err != nil {return err}err = pem.Encode(file, block)if err != nil {return err}//生成PKCS8私钥pk8Stream := MarshalPKCS8PrivateKey(derStream)block = &pem.Block{Type:  "PRIVATE KEY",Bytes: pk8Stream,}file, err = os.Create("pkcs8_private_key.pem")if err != nil {return err}err = pem.Encode(file, block)if err != nil {return err}//生成公钥文件publicKey := &privateKey.PublicKeydefPkix, err := x509.MarshalPKIXPublicKey(publicKey)if err != nil {return err}block = &pem.Block{Type:  "PUBLIC KEY",Bytes: defPkix,}file, err = os.Create("public_key.pem")if err != nil {return err}err = pem.Encode(file, block)if err != nil {return err}return nil}// 由私钥获取PKCS8公钥 这种方式生成的PKCS8与OpenSSL转成的不一样,但是BouncyCastle里可用func MarshalPKCS8PrivateKey(key []byte) []byte {info := struct {Version             intPrivateKeyAlgorithm []asn1.ObjectIdentifierPrivateKey          []byte}{}info.Version = 0info.PrivateKeyAlgorithm = make([]asn1.ObjectIdentifier, 1)info.PrivateKeyAlgorithm[0] = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}info.PrivateKey = keyk, err := asn1.Marshal(info)if err != nil {log.Panic(err.Error())}return k}// 由私钥获取PKCS8公钥func MarshalPKCS8PrivateKey1(key *rsa.PrivateKey) []byte {info := struct {Version             intPrivateKeyAlgorithm []asn1.ObjectIdentifierPrivateKey          []byte}{}info.Version = 0info.PrivateKeyAlgorithm = make([]asn1.ObjectIdentifier, 1)info.PrivateKeyAlgorithm[0] = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}info.PrivateKey = x509.MarshalPKCS1PrivateKey(key)k, err := asn1.Marshal(info)if err != nil {log.Panic(err.Error())}return k}

Rsa加密、解密、签名、验签工具类

//公钥加密私钥解密  私钥签名公钥验证package sdrsaimport ("crypto""crypto/rand""crypto/rsa""crypto/sha256""crypto/x509""encoding/pem""errors")type PriKeyType uintconst (PKCS1 PriKeyType = iotaPKCS8)//私钥签名func Sign(data, privateKey []byte, keyType PriKeyType) ([]byte, error) {h := sha256.New()h.Write(data)hashed := h.Sum(nil)priv, err := getPriKey(privateKey, keyType)if err != nil {return nil, err}return rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA256, hashed)}//公钥验证func SignVer(data, signature, publicKey []byte) error {hashed := sha256.Sum256(data)//获取公钥pub, err := getPubKey(publicKey)if err != nil {return err}//验证签名return rsa.VerifyPKCS1v15(pub, crypto.SHA256, hashed[:], signature)}// 公钥加密func Encrypt(data, publicKey []byte) ([]byte, error) {//获取公钥pub, err := getPubKey(publicKey)if err != nil {return nil, err}//加密return rsa.EncryptPKCS1v15(rand.Reader, pub, data)}// 私钥解密,privateKey为pem文件里的字符func Decrypt(encData, privateKey []byte, keyType PriKeyType) ([]byte, error) {//解析PKCS1a或者PKCS8格式的私钥priv, err := getPriKey(privateKey, keyType)if err != nil {return nil, err}// 解密return rsa.DecryptPKCS1v15(rand.Reader, priv, encData)}func getPubKey(publicKey []byte) (*rsa.PublicKey, error) {//解密pem格式的公钥block, _ := pem.Decode(publicKey)if block == nil {return nil, errors.New("public key error")}// 解析公钥pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)if err != nil {return nil, err}// 类型断言if pub, ok := pubInterface.(*rsa.PublicKey); ok {return pub, nil} else {return nil, errors.New("public key error")}}func getPriKey(privateKey []byte, keyType PriKeyType) (*rsa.PrivateKey, error) {//获取私钥block, _ := pem.Decode(privateKey)if block == nil {return nil, errors.New("private key error!")}var priKey *rsa.PrivateKeyvar err errorswitch keyType {case PKCS1:{priKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)if err != nil {return nil, err}}case PKCS8:{prkI, err := x509.ParsePKCS8PrivateKey(block.Bytes)if err != nil {return nil, err}priKey = prkI.(*rsa.PrivateKey)}default:{return nil, errors.New("unsupport private key type")}}return priKey, nil}

github工程源码

https://github.com/lhtzbj12/go_encryption

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. 一款常用的 Squid 日志分析工具
  3. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  4. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  5. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  6. 【攻克Android(安卓)(1)】安装Android(安卓)Studio,搭建Android开
  7. eclipse / ADT(Android(安卓)Develop Tool) 一些方便的初始设置
  8. 【我的Android进阶之旅】使用Android(安卓)Studio 3.6 的 Androi
  9. Android初学笔记——五:数据存储

随机推荐

  1. Android中10个成功的开源项目
  2. Android推送通知的实现--Android推送通知
  3. android模拟器无法启动问题之中文路径
  4. Android之文件读写
  5. 获取Android 设备信息——build.prop
  6. 转:Activity_dialog效果
  7. 五大Android旗舰机型触摸屏横向评测
  8. android中Selector中的相关属性及配置写
  9. Android的两种拍照方法
  10. android Thumbnail攻略