function decrypt($key, $infilename, $outfilename = "") {

if (!$outfilename) {

$outfilename = $infilename.'.dec';

}

$cipher_str = file_get_contents($infilename);

if (!$cipher_str) {

die("empty file".PHP_EOL);

}

$file_size = substr($cipher_str, 0, 8);

$file_size = unpack("P", $file_size);

$iv = substr($cipher_str, 8, 16);

$cipher_str = substr($cipher_str, 24);

$plain_str = openssl_decrypt($cipher_str, "aes-256-cbc", $key, 3, $iv);

$plain_str = substr($plain_str, 0, $file_size[1]);

file_put_contents($outfilename, $plain_str);

echo "decrypted output file ".$outfilename.PHP_EOL;

}

function encrypt($key, $infilename, $outfilename) {

if (!$outfilename) {

$outfilename = $infilename.'.enc';

}

$plain_str = file_get_contents($infilename);

if (!$plain_str) {

die("empty file".PHP_EOL);

}

$file_size = strlen($plain_str);

$file_size = pack("P", $file_size);

$iv = random_bytes(16);

if (strlen($plain_str) % 16 != 0) {

$bytesToPad = 16 - (strlen($plain_str) % 16);

$plain_str = $plain_str . random_bytes($bytesToPad);

}

$cipher_str = openssl_encrypt($plain_str, "aes-256-cbc", $key, 3, $iv);

$cipher_str = $file_size.$iv.$cipher_str;

file_put_contents($outfilename, $cipher_str);

echo "encrypted output file ".$outfilename.PHP_EOL;

}

$arg = getopt('e::d::k:i:o:');

if (isset($arg['i']) && !empty($arg['i'])) {

$infilename = $arg['i'];

} else {

die("please input filename".PHP_EOL);

}

if (isset($arg['o']) && !empty($arg['o'])) {

$outfilename = $arg['o'];

} else {

$outfilename = "";

}

if (isset($arg['k']) && !empty($arg['k'])) {

$key = $arg['k'];

} else {

$key = "pass";

}

$key = hash('sha256', $key, true);

if (isset($arg['d'])) {

decrypt($key, $infilename, $outfilename);

} elseif (isset($arg['e'])) {

encrypt($key, $infilename, $outfilename);

}

golang cbc使用pkcs7补全版:package main

import (

"bytes"

"crypto/aes"

"crypto/cipher"

"crypto/rand"

"crypto/sha256"

//"encoding/binary"

"flag"

"fmt"

"io/ioutil"

"log"

"os"

)

func pkcs7strip(data *[]byte, blockSize int) (int, error) {

length := len(*data)

if length == 0 {

return 0, fmt.Errorf("pkcs7: Data is empty")

}

if length%blockSize != 0 {

return 0, fmt.Errorf("pkcs7: Data is not block-aligned")

}

padLen := int((*data)[length-1])

ref := bytes.Repeat([]byte{byte(padLen)}, padLen)

if padLen > blockSize || padLen == 0 || !bytes.HasSuffix(*data, ref) {

return 0, fmt.Errorf("pkcs7: Invalid padding")

}

return length-padLen, nil

}

func pkcs7pad(data *[]byte, blockSize int) error {

if blockSize < 0 || blockSize > 256 {

return fmt.Errorf("pkcs7: Invalid block size %d", blockSize)

} else {

padLen := blockSize - len(*data) % blockSize

padding := bytes.Repeat([]byte{byte(padLen)}, padLen)

*data = append(*data, padding...)

return nil

}

}

func encryptFile(key []byte, filename string, outFilename string) (string, error) {

if len(outFilename) == 0 {

outFilename = filename + ".enc"

}

plaintext, err := ioutil.ReadFile(filename)

if err != nil {

return "", err

}

of, err := os.Create(outFilename)

if err != nil {

return "", err

}

defer of.Close()

if err := pkcs7pad(&plaintext, aes.BlockSize) ; err != nil {

return "", err

}

iv := make([]byte, aes.BlockSize)

if _, err := rand.Read(iv); err != nil {

return "", err

}

if _, err = of.Write(iv); err != nil {

return "", err

}

ciphertext := make([]byte, len(plaintext))

block, err := aes.NewCipher(key)

if err != nil {

return "", err

}

mode := cipher.NewCBCEncrypter(block, iv)

mode.CryptBlocks(ciphertext, plaintext)

if _, err = of.Write(ciphertext); err != nil {

return "", err

}

return outFilename, nil

}

func decryptFile(key []byte, filename string, outFilename string) (string, error) {

if len(outFilename) == 0 {

outFilename = filename + ".dec"

}

ciphertext, err := ioutil.ReadFile(filename)

if err != nil {

return "", err

}

of, err := os.Create(outFilename)

if err != nil {

return "", err

}

defer of.Close()

buf := bytes.NewReader(ciphertext)

iv := make([]byte, aes.BlockSize)

if _, err = buf.Read(iv); err != nil {

return "", err

}

paddedSize := len(ciphertext) - aes.BlockSize

if paddedSize%aes.BlockSize != 0 {

return "", fmt.Errorf("want padded plaintext size to be aligned to block size")

}

plaintext := make([]byte, paddedSize)

block, err := aes.NewCipher(key)

if err != nil {

return "", err

}

mode := cipher.NewCBCDecrypter(block, iv)

mode.CryptBlocks(plaintext, ciphertext[aes.BlockSize:])

origSize, err := pkcs7strip(&plaintext, aes.BlockSize)

if err != nil {

return "", err

}

if _, err := of.Write(plaintext[:origSize]); err != nil {

return "", err

}

return outFilename, nil

}

func main() {

var keyFlag string

encFlag := flag.Bool("e", false, "encrypt")

decFlag := flag.Bool("d", false, "decrypt")

flag.StringVar(&keyFlag, "k", "password", "encrypt password")

flag.Parse()

filename := flag.Arg(0)

key := sha256.Sum256([]byte(keyFlag))

fmt.Println("use password", keyFlag)

//fmt.Println(key)

if *encFlag {

outFilename, err := encryptFile(key[:], filename, "")

if err != nil {

log.Fatal(err)

}

fmt.Println("Encrypted output file:", outFilename)

} else if *decFlag {

outFilename, err := decryptFile(key[:], filename, "")

if err != nil {

log.Fatal(err)

}

fmt.Println("Decrypted output file:", outFilename)

} else {

fmt.Println(flag.Usage)

os.Exit(1)

}

}

golang使用aes cfb:package main

import (

//"bytes"

"crypto/aes"

"crypto/cipher"

"crypto/rand"

"crypto/sha256"

//"encoding/binary"

"flag"

"fmt"

"io"

"io/ioutil"

"log"

"os"

)

func encryptFile(key []byte, filename string, outFilename string) (string, error) {

if len(outFilename) == 0 {

outFilename = filename + ".enc"

}

plaintext, err := ioutil.ReadFile(filename)

if err != nil {

return "", err

}

of, err := os.Create(outFilename)

if err != nil {

return "", err

}

defer of.Close()

block, err := aes.NewCipher(key)

if err != nil {

panic(err)

}

ciphertext := make([]byte, aes.BlockSize+len(plaintext))

iv := ciphertext[:aes.BlockSize]

if _, err := io.ReadFull(rand.Reader, iv); err != nil {

panic(err)

}

stream := cipher.NewCFBEncrypter(block, iv)

stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)

fmt.Printf("iv:\t%x\n", iv)

fmt.Printf("cipher text:\t%x\n", ciphertext)

if _, err = of.Write(ciphertext); err != nil {

return "", err

}

return outFilename, nil

}

func decryptFile(key []byte, filename string, outFilename string) (string, error) {

if len(outFilename) == 0 {

outFilename = filename + ".dec"

}

ciphertext, err := ioutil.ReadFile(filename)

fmt.Printf("cipher text:\t%x\n", ciphertext)

if err != nil {

return "", err

}

of, err := os.Create(outFilename)

if err != nil {

return "", err

}

defer of.Close()

block, err := aes.NewCipher(key)

if err != nil {

panic(err)

}

iv := ciphertext[:aes.BlockSize]

ciphertext = ciphertext[aes.BlockSize:]

fmt.Printf("cipher2 text:\t%x\n", ciphertext)

fmt.Printf("iv:\t%x\n", iv)

stream := cipher.NewCFBDecrypter(block, iv)

stream.XORKeyStream(ciphertext, ciphertext)

if _, err := of.Write(ciphertext); err != nil {

return "", err

}

return outFilename, nil

}

func main() {

var keyFlag string

encFlag := flag.Bool("e", false, "encrypt")

decFlag := flag.Bool("d", false, "decrypt")

flag.StringVar(&keyFlag, "k", "password", "encrypt password")

flag.Parse()

filename := flag.Arg(0)

key := sha256.Sum256([]byte(keyFlag))

fmt.Println("use password", keyFlag)

//fmt.Println(key)

if *encFlag {

outFilename, err := encryptFile(key[:], filename, "")

if err != nil {

log.Fatal(err)

}

fmt.Println("Encrypted output file:", outFilename)

} else if *decFlag {

outFilename, err := decryptFile(key[:], filename, "")

if err != nil {

log.Fatal(err)

}

fmt.Println("Decrypted output file:", outFilename)

} else {

fmt.Println(flag.Usage)

os.Exit(1)

}

}