AES算法

说明

  1. 主要用于隐私数据加密
  2. 使用128位ECB模式的AES加密算法
  3. 密钥联系解决方案获取
  4. 在线工具,使用方式选择:模式-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)
    })
}

results matching ""

    No results matching ""