AES CBC加解密

荒凉一梦 提交于 2019-12-19 03:47:45

项目中用到AES-128-CBC加密模式,服务端客户端采用不同语言开发,记录不同语言AES的实现。

AES加密数据块分组长度必须为128比特,密钥长度可以是128比特、192比特、256比特中的任意一个(如果数据块及密钥长度不足时,会补齐,补齐的是size)。

 

1. NodeJS

var crypto = require('crypto')

// AES 加密
function encryptstring(str) {
	var cipher = crypto.createCipheriv('aes-128-cbc', '1234567812345678', '1234567812345678'),
	encrypted = cipher.update(str, 'utf-8', 'base64');
	encrypted += cipher.final('base64');
	return encrypted;
}

console.log(encryptstring("hello world"))

$ node aes.js
a2SpM37nvVYtBnVHonX86w==

 

2. Golang

package main

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"fmt"
)

const (
	KEY   = "1234567812345678"
	IV    = "1234567812345678"
)

// AES 加密
func AesEncrypt(encodeStr string, key []byte) (string, error) {
	encodeBytes := []byte(encodeStr)
	//根据key 生成密文
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	blockSize := block.BlockSize()
	encodeBytes = PKCS5Padding(encodeBytes, blockSize)

	blockMode := cipher.NewCBCEncrypter(block, []byte(IV))
	crypted := make([]byte, len(encodeBytes))
	blockMode.CryptBlocks(crypted, encodeBytes)

	return base64.StdEncoding.EncodeToString(crypted), nil
}

// 16字节为一组,填充为16字节倍数
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	// 填充size
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)

	return append(ciphertext, padtext...)
}

// AES 解密
func AesDecrypt(decodeStr string, key []byte) ([]byte, error) {
	//先解密base64
	decodeBytes, err := base64.StdEncoding.DecodeString(decodeStr)
	if err != nil {
		return nil, err
	}
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	blockMode := cipher.NewCBCDecrypter(block, []byte(IV))
	origData := make([]byte, len(decodeBytes))

	blockMode.CryptBlocks(origData, decodeBytes)
	origData = PKCS5UnPadding(origData)
	return origData, nil
}


// 移除Padding
func PKCS5UnPadding(origData []byte) []byte {
	length := len(origData)
	unpadding := int(origData[length-1])

    // 移除填充的size
	return origData[:(length - unpadding)]
}


/// main
func main() {
	// 加密
	dstr, _ := AesEncrypt("hello world", []byte(KEY))
	fmt.Println("Encrypt: ", string(dstr))

	// 解密
	sstr, _ := AesDecrypt(string(dstr), []byte(KEY))
	fmt.Println("Decrypt: ", string(sstr))
}

Encrypt:  a2SpM37nvVYtBnVHonX86w==
Decrypt:  hello world

 

3. Python

#!/usr/bin/python

from Crypto.Cipher import AES
import base64

key = '1234567812345678'
iv = '1234567812345678'

def encry(data):
	pad_it = lambda s: s + (16 - len(s) % 16) * chr(16 - len(s) % 16)

	generator = AES.new(key, AES.MODE_CBC, iv)
	crypt = generator.encrypt(pad_it(data))
	cryptedStr = base64.b64encode(crypt)
	return cryptedStr

def decrypt(data):
	data = base64.b64decode(data)
	generator = AES.new(key, AES.MODE_CBC, iv)
	crypt = generator.decrypt(data)
	
	padLen = ord(crypt[len(crypt) -1])
	return crypt[0: -padLen]


if __name__ == "__main__":
	str = encry("hello world")
	print str		# a2SpM37nvVYtBnVHonX86w==
	
	str = decrypt(str)
	print str		# hello world

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!