因为项目的需要用到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. HDU 2653 (记忆化BFS搜索+优先队列)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2653 题目大意:迷宫中有普通点和陷阱.其中普通点可以走可以飞,但是陷阱只能飞.走耗时1,飞耗时2.但 ...

  2. 让ORACLE LIKE 时不区分大小写

    select * from t_resource_base where xdkm_id = '08975DBC-953B-42DC-AA01-65F168891CEE' and regexp_like ...

  3. BZOJ1224: [HNOI2002]彩票

    Description 某地发行一套彩票.彩票上写有1到M这M个自然数.彩民可以在这M个数中任意选取N个不同的数打圈.每个彩民只能买一张彩票,不同的彩民的彩票上的选择不同.每次抽奖将抽出两个自然数X和 ...

  4. 全面解析Linux数字文件权限

    全面解析Linux数字文件权限 来源:   时间:2013-09-04 20:35:13   阅读数:11433 分享到:0 [导读] 在刚开始接触Linux时对于文件权限的理解并不是很透彻,这里详细 ...

  5. winform学习之----图片控件应用(上一张,下一张)

    示例1: int i = 0;        string[] path = Directory.GetFiles(@"C:\Users\Administrator\Desktop\图片&q ...

  6. QComboBox 和 QSpinBox 使用方法

    Qt中QComboBox 和 QSpinBox 是两个很常用的空间,QComboBox 是下拉菜单,而 QSpinBox 是调参数的神器,所以它们的用法十分必要熟练掌握. 首先来看 QComboBox ...

  7. jQuery 事件的命名空间

    在没有看到这篇 文章之前,我一直不知道原来bind也可以有命名空间.事实上,我看完这篇文章后,再去翻了一下手册,也才发现了一点点的注释.但手册也仅仅是一句话就带 过去了.没有过多的深究,或许他认为命名 ...

  8. CSS3:背景

    细节注意 盒子:border-box | padding-box | content-box用于background-origin背景的开始和background-clip的剪切位置. 渐变也是生成一 ...

  9. SqlServer表数据与excel中数据的互相复制

    一.SqlServer表数据复制到excel 1.新建查询,用sql语句把表数据读出来 2.然后,选择数据,右键,复制(也可以点击连同标题复制),复制到记事本中(不然会乱码) 3.然后再把记事本的内容 ...

  10. hibernate将本地SQL查询结果封装成对象

    hibernate将本地SQL查询结果封装成对象 不知道大家有没有碰过这种情况,迫于很多情况只能用native SQL来查询(如:复杂统计等),然而使用native查询后,结果会被放到object里, ...