AES算法
说明
- 主要用于隐私数据加密
- 使用128位ECB模式的AES加密算法
- 密钥联系解决方案获取
- 在线工具,使用方式选择:模式-ECB,填充-Pkcs7,密文编码-Base64,偏移量无需填写
算法实现
php版本
<?php
class Aes
{
/**
* @desc aes加密
*
* @param $input 明文
* @param $key 密钥
* @return string 密文
*/
public function encrypt($input, $key)
{
$size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$input = $this->pkcs5_pad($input, $size);
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$data = base64_encode($data);
return $data;
}
/**
* @desc aes解密
*
* @param $cipher 密文
* @param $key 密钥
* @return bool|string 密文
*/
public function decrypt($cipher, $key)
{
$decrypted= mcrypt_decrypt(
MCRYPT_RIJNDAEL_128,
$key,
base64_decode($cipher),
MCRYPT_MODE_ECB
);
$dec_s = strlen($decrypted);
$padding = ord($decrypted[$dec_s-1]);
$decrypted = substr($decrypted, 0, -$padding);
return $decrypted;
}
private function pkcs5_pad ($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
}
go版本
package helper
import (
"encoding/base64"
"errors"
"fmt"
)
// Decrypt AES PKC#7解密
func Base64AESDecrypt(secretKey, ciphertext string) (response string, err error) {
defer func() {
if rErr := recover();rErr != nil{
err = errors.New(fmt.Sprintf("解密失败panic-%v",rErr))
//log.Trace.Errorf(context.Background(),consts.DL_TAG_PANIC_RECOVER,"msg=%v-%s",rErr,string(debug.Stack()))
}
}()
enc, err := base64.StdEncoding.DecodeString(ciphertext)
if err != nil {
// todo log
return
}
// ECB解密
origin, err := AesDecrypt(enc, []byte(secretKey))
if err != nil {
// todo log
return
}
// 使用PKCS#7对解密后的内容去除填充
response = string(PKCS7UnPadding(origin))
return
}
// Encrypt AES PKC#7解密
func Base64AESEncrypt(secretKey, content string) (response string, err error) {
defer func() {
if rErr := recover();rErr != nil{
err = errors.New(fmt.Sprintf("加密失败panic-%v",rErr))
//log.Trace.Errorf(context.Background(),consts.DL_TAG_PANIC_RECOVER,"msg=%v-%s",rErr,string(debug.Stack()))
}
}()
//使用PKCS#7对原文进行填充,BlockSize为16字节
ciphertext := PKCS7Padding([]byte(content), 16)
//ECB加密
crypted, err := AesEncrypt(ciphertext, []byte(secretKey))
if err != nil {
// todo log
return
}
response = base64.StdEncoding.EncodeToString(crypted)
return
}
package helper
// AES 解密逻辑处理
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"errors"
)
// AesEncrypt Aes/ECB模式的加密方法,PKCS7填充方式
func AesEncrypt(src, key []byte) ([]byte, error) {
Block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
if len(src) == 0 {
return nil, errors.New("plaintext empty")
}
mode := NewECBEncrypter(Block)
ciphertext := src
mode.CryptBlocks(ciphertext, ciphertext)
return ciphertext, nil
}
// AesDecrypt Aes/ECB模式的解密方法,PKCS7填充方式
func AesDecrypt(src, key []byte) ([]byte, error) {
Block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
if len(src) == 0 {
return nil, errors.New("plaintext empty")
}
mode := NewECBDecrypter(Block)
ciphertext := src
mode.CryptBlocks(ciphertext, ciphertext)
return ciphertext, nil
}
// ECB模式结构体
type ecb struct {
b cipher.Block
blockSize int
}
// 实例化ECB对象
func newECB(b cipher.Block) *ecb {
return &ecb{
b: b,
blockSize: b.BlockSize(),
}
}
// ECB加密类
type ecbEncrypter ecb
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])
dst = dst[x.blockSize:]
src = src[x.blockSize:]
}
}
// ECB解密类
type ecbDecrypter ecb
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])
dst = dst[x.blockSize:]
src = src[x.blockSize:]
}
}
// PKCS7Padding PKCS7填充
func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
// PKCS7UnPadding PKCS7去除
func PKCS7UnPadding(ciphertext []byte) []byte {
length := len(ciphertext)
unpadding := int(ciphertext[length-1])
return ciphertext[:(length - unpadding)]
}
// ZerosPadding 零点填充
func ZerosPadding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(0)}, padding)
return append(ciphertext, padtext...)
}
// ZerosUnPadding 零点去除
func ZerosUnPadding(ciphertext []byte) []byte {
return bytes.TrimFunc(ciphertext, func(r rune) bool {
return r == rune(0)
})
}