AES128加密、AES128解密、AES256加密、AES256解密

AES 这个标准用来替代原先的 DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院 (NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一 。

该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijdael之名命之,投稿高级加密标准的甄选流程。(Rijdael的发音近于 "Rhine doll"。)

Rijndael密码的设计力求满足以下3条标准:

① 抵抗所有已知的攻击。② 在多个平台上运算速度快,编码紧凑。③ 设计简单。

(新)AES-128 加密 | AES-256 加密 (新)AES-128 解密 | AES-256 解密 (旧)AES128 加密 | AES256 加密 (旧)AES 128 解密 | AES 256 解密

Example PHP

示例 #1 PHP 7.1+ AES-128 加密、解密之 GCM 模式的示例
<?php
// $key should have been previously generated in a cryptographically safe way, like openssl_random_pseudo_bytes
$plaintext = "message to be encrypted";
$cipher = "aes-128-gcm";
$key = "secretkey0123456";
$tag = null;
if (in_array($cipher, openssl_get_cipher_methods()))
{
    $ivlen = openssl_cipher_iv_length($cipher);
    // Generate a pseudo-random string of bytes
    $iv = openssl_random_pseudo_bytes($ivlen);
    $ciphertext = openssl_encrypt($plaintext, $cipher, $key, $options=0, $iv, $tag);
    echo $ciphertext."\n";
    //store $cipher, $iv, and $tag for decryption later
    $original_plaintext = openssl_decrypt($ciphertext, $cipher, $key, $options=0, $iv, $tag);
    echo $original_plaintext."\n";
}

AES-128 加密的结果($ciphertext 变量的值。因为IV是随机值,因此大家得到的结果不同):xtnpPNP1fRJSoLAP9ZErDpRnIYX2RMo=
AES-128 解密的结果($original_plaintext 变量的值):message to be encrypted

示例 #2 PHP 7.1+ AES-256 加密、解密之 CBC 模式的示例
<?php
$plaintext = "message to be encrypted";
$cipher = "aes-256-cbc";
$key = "secretkey0123456";
if (in_array($cipher, openssl_get_cipher_methods()))
{
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = '1111112222220000';
    // 加密
    $ciphertext = openssl_encrypt($plaintext, $cipher, $key, $options=0, $iv);
    echo 'ciphertext: ', $ciphertext, "\n";
    // 解密
    $original_plaintext = openssl_decrypt($ciphertext, $cipher, $key, $options=0, $iv);
    echo 'original_plaintext: ', $original_plaintext,"\n";
}

AES-256 加密的结果($ciphertext 变量的值。因为IV是随机值,因此大家得到的结果不同): Ae7g2i8YdcGiEvf1W1VmKTCe8YQhVsqrevvYxDL6RpU=
AES-256 解密的结果($original_plaintext 变量的值): message to be encrypted

Example Go

示例 #1 Go 1.22.2 linux/amd64 AES-128 加密解密 CBC 模式的示例
备注:该示例适用于 AES-128、AES-192、AES-256;在 Go 语言中秘钥的长度 16/24/32 决定加密强度 AES-128/AES-192/AES-256。
package main

import (
    "bytes"
    "crypto/aes"
    "crypto/cipher"
    "crypto/rand"
    "encoding/base64"
    "errors"
    "fmt"
    "io"
    "log"
)

func main() {
    // 加密的秘钥
    key := []byte("secretkey0123456")
    // 加密的内容
    plaintext := []byte("message to be encrypted")
    // 生成随机IV值
    iv := make([]byte, 16)
    if _, err := io.ReadFull(rand.Reader, iv); err != nil {
        log.Fatal(err)
    }
    // 获取cipher.block
    block, err := aes.NewCipher(key)
    if err != nil {
        panic(err)
    }
    // 明文长度补位
    plaintext = PKCS7Padding(plaintext, block.BlockSize())
    if len(plaintext)%aes.BlockSize != 0 {
        return nil, errors.New("plaintext is not a multiple of the block size")
    }
    ciphertext := make([]byte, len(plaintext))
    mode := cipher.NewCBCEncrypter(block, iv)
    // 把明文换算成密文
    mode.CryptBlocks(ciphertext, plaintext)
    // ciphertext 是二进制数据
    // 使用base64编码输出加密的结果
    fmt.Printf("%s\n", base64.StdEncoding.EncodeToString(ciphertext))

    // 解密代码段
    // 实战中,务必保存IV和key两个值
    mode = cipher.NewCBCDecrypter(block, iv)
    // 把密文还原成明文
    mode.CryptBlocks(ciphertext, ciphertext)
    // 去掉补位内容
    ciphertext, _ = PKCS7Unpadding(ciphertext)
    fmt.Printf("%s\n", ciphertext)
}

// 采用 PKCS7Padding 补位
func PKCS7Padding(plaintext []byte, blockSize int) []byte {
    padding := blockSize - len(plaintext)%blockSize
    padtext := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(plaintext, padtext...)
}

// 去掉 PKCS7Padding 补位的内容
func PKCS7Unpadding(plaintext []byte) ([]byte, error) {
    length := len(plaintext)
    unpadding := int(plaintext[length-1])
    if length-unpadding < 0 {
        return nil, errors.New("PKCS7Unpadding error")
    }
    return plaintext[:(length - unpadding)], nil
}      

AES-128 加密的结果(ciphertext 变量的值。因为IV是随机值,因此大家得到的结果不同):yk3s53MmpYLL/2SyHGnEdVcblNwwxnFVUy3kJVPi268=
AES-128 解密的结果:message to be encrypted