因为项目的需要用到golang的一种特殊的加密解密算法AES/ECB/PKCS5,但是算法并没有包含在标准库中,经过多次失败的尝试,终于解码成功,特此分享:

/*
描述 : golang AES/ECB/PKCS5 加密解密
date : 2016-04-08
*/ package main import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
"strings"
) func main() {
/*
*src 要加密的字符串
*key 用来加密的密钥 密钥长度可以是128bit、192bit、256bit中的任意一个
*16位key对应128bit
*/
src := "0.56"
key := "0123456789abcdef" crypted := AesEncrypt(src, key)
AesDecrypt(crypted, []byte(key))
Base64URLDecode("39W7dWTd_SBOCM8UbnG6qA")
} func Base64URLDecode(data string) ([]byte, error) {
var missing = (4 - len(data)%4) % 4
data += strings.Repeat("=", missing)
res, err := base64.URLEncoding.DecodeString(data)
fmt.Println(" decodebase64urlsafe is :", string(res), err)
return base64.URLEncoding.DecodeString(data)
} func Base64UrlSafeEncode(source []byte) string {
// Base64 Url Safe is the same as Base64 but does not contain '/' and '+' (replaced by '_' and '-') and trailing '=' are removed.
bytearr := base64.StdEncoding.EncodeToString(source)
safeurl := strings.Replace(string(bytearr), "/", "_", -1)
safeurl = strings.Replace(safeurl, "+", "-", -1)
safeurl = strings.Replace(safeurl, "=", "", -1)
return safeurl
} func AesDecrypt(crypted, key []byte) []byte {
block, err := aes.NewCipher(key)
if err != nil {
fmt.Println("err is:", err)
}
blockMode := NewECBDecrypter(block)
origData := make([]byte, len(crypted))
blockMode.CryptBlocks(origData, crypted)
origData = PKCS5UnPadding(origData)
fmt.Println("source is :", origData, string(origData))
return origData
} func AesEncrypt(src, key string) []byte {
block, err := aes.NewCipher([]byte(key))
if err != nil {
fmt.Println("key error1", err)
}
if src == "" {
fmt.Println("plain content empty")
}
ecb := NewECBEncrypter(block)
content := []byte(src)
content = PKCS5Padding(content, block.BlockSize())
crypted := make([]byte, len(content))
ecb.CryptBlocks(crypted, content)
// 普通base64编码加密 区别于urlsafe base64
fmt.Println("base64 result:", base64.StdEncoding.EncodeToString(crypted)) fmt.Println("base64UrlSafe result:", Base64UrlSafeEncode(crypted))
return crypted
} func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
} func PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
// 去掉最后一个字节 unpadding 次
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
} type ecb struct {
b cipher.Block
blockSize int
} func newECB(b cipher.Block) *ecb {
return &ecb{
b: b,
blockSize: b.BlockSize(),
}
} type ecbEncrypter ecb // NewECBEncrypter returns a BlockMode which encrypts in electronic code book
// mode, using the given Block.
func NewECBEncrypter(b cipher.Block) cipher.BlockMode {
return (*ecbEncrypter)(newECB(b))
}
func (x *ecbEncrypter) BlockSize() int { return x.blockSize }
func (x *ecbEncrypter) CryptBlocks(dst, src []byte) {
if len(src)%x.blockSize != 0 {
panic("crypto/cipher: input not full blocks")
}
if len(dst) < len(src) {
panic("crypto/cipher: output smaller than input")
}
for len(src) > 0 {
x.b.Encrypt(dst, src[:x.blockSize])
src = src[x.blockSize:]
dst = dst[x.blockSize:]
}
} type ecbDecrypter ecb // NewECBDecrypter returns a BlockMode which decrypts in electronic code book
// mode, using the given Block.
func NewECBDecrypter(b cipher.Block) cipher.BlockMode {
return (*ecbDecrypter)(newECB(b))
}
func (x *ecbDecrypter) BlockSize() int { return x.blockSize }
func (x *ecbDecrypter) CryptBlocks(dst, src []byte) {
if len(src)%x.blockSize != 0 {
panic("crypto/cipher: input not full blocks")
}
if len(dst) < len(src) {
panic("crypto/cipher: output smaller than input")
}
for len(src) > 0 {
x.b.Decrypt(dst, src[:x.blockSize])
src = src[x.blockSize:]
dst = dst[x.blockSize:]
}
}

这是作者对多篇博客和代码整理而成,如果您觉得本文对您有帮助,欢迎打赏一杯咖啡作为对作者的鼓励,谢谢!

鸣谢:

Go加密解密之AES:http://blog.studygolang.com/tag/aes_encrypt/

yinheli: https://gist.github.com/yinheli/3370e0e901329b639be4

golang AES/ECB/PKCS5 加密解密 url-safe-base64的更多相关文章

  1. C#调用Crypto++库AES ECB CBC加解密

    本文章使用上一篇<C#调用C++类库例子>的项目代码作为Demo.本文中,C#将调用C++的Crypto++库,实现AES的ECB和CBC加解密. 一.下载Crypto 1.进入Crypt ...

  2. python 实现 AES ECB模式加解密

    AES ECB模式加解密使用cryptopp完成AES的ECB模式进行加解密. AES加密数据块分组长度必须为128比特,密钥长度可以是128比特.192比特.256比特中的任意一个.(8比特 == ...

  3. 微信小程序aes前后端加密解密交互

    aes前后端加密解密交互 小程序端 1. 首先引入aes.js /** * [description] CryptoJS v3.1.2 * [description] zhuangzhudada so ...

  4. AES ECB PKCS5/PKCS7 加解密 python实现 支持中文

    目录 ECB模式介绍 pkcs5padding和pkcs7padding的区别 python实现 注意事项 ECB模式介绍 电码本模式(Electronic Codebook Book (ECB) 这 ...

  5. Android DES加密的CBC模式加密解密和ECB模式加密解密

    DES加密共有四种模式:电子密码本模式(ECB).加密分组链接模式(CBC).加密反馈模式(CFB)和输出反馈模式(OFB). CBC模式加密: import java.security.Key; i ...

  6. Java使用AES算法进行加密解密

    一.加密 /** * 加密 * @param src 源数据字节数组 * @param key 密钥字节数组 * @return 加密后的字节数组 */ public static byte[] En ...

  7. AES不同语言加密解密

    AES加密模式和填充方式:还有其他 算法/模式/填充 16字节加密后数据长度 不满16字节加密后长度 AES/CBC/NoPadding 16 不支持 AES/CBC/PKCS5Padding 32 ...

  8. AES字节数组加密解密流程

    AES类时微软MSDN中最常用的加密类,微软官网也有例子,参考链接:https://docs.microsoft.com/zh-cn/dotnet/api/system.security.crypto ...

  9. 自己写的AES和RSA加密解密工具

    package com.sdyy.common.utils; import java.security.Key; import java.security.KeyFactory; import jav ...

随机推荐

  1. CC150 - 11.3

    Question: Given a sorted array of n integers that has been rotated an unknown number of times, write ...

  2. Hibernate使用MyExclipse10自动生成配置文件报错

    使用MyExclipse10自动生成hibernate映射文件如下: 结果发现启动服务时报以下错误: 原因:因为hibernate换过项目地址,所以dtd文件的地址也换掉了.在hbm.xml文件里面把 ...

  3. Apache Commons CLI 简介

    CLI 命令代码实现 命令行程序处理流程相对比较简单,主要流程为设定命令行参数 -> 解析输入参数 -> 使用输入的数据进行逻辑处理CLI 定义阶段 每一条命令行都必须定义一组参数,它们被 ...

  4. 诅咒JavaScript之----ArcGIS JavaScript 点聚合 ClusterLayer

    对一个之前一直做winForm的 菜鸟来说,突然接触这么神奇的语言,基本上每天都会诅咒一下这门神奇的语言. 最近做了一个小网站,底图用的是天地图的服务,用ArcGIS JavaScript提供的一些G ...

  5. IIS权限设置

    Check in the IIS Manager to see what authentication type is enabled on the directories that are part ...

  6. Go学习记录

    操作系统:Windows 一.下载 go官网:https://golang.org/go下载地址:https://golang.org/dl/ 二.安装 安装包有msi安装版本,以及zip压缩包版本. ...

  7. git命令常见问题总结

    1.git如何放弃所有本地修改 git checkout . #本地所有修改的.没有的提交的,都返回到原来的状态 git stash #把所有没有提交的修改暂存到stash里面.可用git stash ...

  8. 《Pro Git》笔记1:起步

    第一章 起步 1.关于版本控制 版本控制用于记录和追踪目录结构和文件内容变化,能够追溯过去的任何修改和变化,并恢复到任何历史状态. 版本控制系统可以按照发展过程分成以下几类: 目录备份.记录版本变化最 ...

  9. [ZZ] HD7970GE vs GTX770

    AMD/NV烽烟再起!HD7970GE大战GTX770 泡泡网显卡频道7月8日 高端市场肩负展示厂商实力,树立品牌形象的任务,历来是兵家必争之地.从GTX680 VS HD7970,HD7970GE ...

  10. spring mvc返回json字符串数据,只需要返回一个java bean对象就行,只要这个java bean 对象实现了序列化serializeable

    1.spring mvc返回json数据,只需要返回一个java bean对象就行,只要这个java bean 对象实现了序列化serializeable 2. @RequestMapping(val ...