AES加密算法涉及4种操作:字节替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥加(AddRoundKey)。
对AES加密算法感兴趣的不妨看看这个文章:
https://www.cnblogs.com/luop/p/4334160.html
先上PHP版本的,比较简单:
function AesData($str, $op = 'enc', $key)
{
$code = '';
if(!empty($str) && !empty($key)) {
$iv = substr(md5($key), 0, 16);
switch ($op) {
case 'enc':
$code = openssl_encrypt($str, 'AES-128-CBC', $key, 0 ,$iv);
break;
case 'dec':
$code = openssl_decrypt($str, 'AES-128-CBC', $key, 0, $iv);
break;
default:
$code = $str;
break;
}
}
return $code;
}
再上python版本:
#coding=utf8
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
import base64
import hashlib
class PrpCrypt(object):
def __init__(self, key):
self.key = key
self.mode = AES.MODE_CBC
self.iv = ""
def md5sum(self,tmp):
m = hashlib.md5()
m.update(tmp.encode("utf8"))
return m.hexdigest()
def setKEYandIV(self):
tmp = self.md5sum(self.key)
self.iv = tmp[0:16].encode("utf8")
self.key = self.key.encode("utf8")
def encrypt(self, text):
data = pad(text.encode('utf8'),16)
cipher = AES.new(self.key, self.mode, self.iv)
encryptedbytes = cipher.encrypt(data)
encodestrs = base64.b64encode(encryptedbytes)
enctext = encodestrs.decode('utf8')
return enctext
def decrypt(self, text):
cryptor = AES.new(self.key, self.mode, self.iv)
encodebytes = base64.decodebytes(text)
#需要注意进行base64解码字符串
plain_text = cryptor.decrypt(encodebytes)
plain_text = unpad(plain_text,16)
return plain_text.decode("utf8")
tmp = b'xxxxxxxxxxxxxxxxx' #自己加密完的数据
key = "xxxxx" #自己定义
obj = PrpCrypt(key)
obj.setKEYandIV()
tmp2 = obj.decrypt(tmp)
print(tmp2)
obj2 = PrpCrypt(key)
obj2.setKEYandIV()
tmp3 = obj2.encrypt(tmp2)
print(tmp3)
?解密时需要注意进行base64解码 encodebytes?=?base64.decodebytes(text)
加密时需要注意进行base64编码
encodestrs?=?base64.b64encode(encryptedbytes)
重点注意python需要进行base64加解码,而PHP封装过度,帮你实现了base64这部分,真不知道这是好还是不好?
/* {{{ proto string openssl_decrypt(string data, string method, string password [, int options=0 [, string $iv = ''[, string $tag = ''[, string $aad = '']]]])
Takes raw or base64 encoded string and decrypts it using given method and key */
PHP_FUNCTION(openssl_decrypt)
{
zend_long options = 0;
char *data, *method, *password, *iv = "", *tag = NULL, *aad = "";
size_t data_len, method_len, password_len, iv_len = 0, tag_len = 0, aad_len = 0;
const EVP_CIPHER *cipher_type;
EVP_CIPHER_CTX *cipher_ctx;
struct php_openssl_cipher_mode mode;
int i = 0, outlen;
zend_string *outbuf;
zend_string *base64_str = NULL;
zend_bool free_iv = 0, free_password = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|lsss", &data, &data_len, &method, &method_len,
&password, &password_len, &options, &iv, &iv_len, &tag, &tag_len, &aad, &aad_len) == FAILURE) {
return;
}
if (!method_len) {
php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
RETURN_FALSE;
}
PHP_OPENSSL_CHECK_SIZE_T_TO_INT(data_len, data);
PHP_OPENSSL_CHECK_SIZE_T_TO_INT(password_len, password);
PHP_OPENSSL_CHECK_SIZE_T_TO_INT(aad_len, aad);
PHP_OPENSSL_CHECK_SIZE_T_TO_INT(tag_len, tag);
cipher_type = EVP_get_cipherbyname(method);
if (!cipher_type) {
php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
RETURN_FALSE;
}
cipher_ctx = EVP_CIPHER_CTX_new();
if (!cipher_ctx) {
php_error_docref(NULL, E_WARNING, "Failed to create cipher context");
RETURN_FALSE;
}
php_openssl_load_cipher_mode(&mode, cipher_type);
if (!(options & OPENSSL_RAW_DATA)) {
base64_str = php_base64_decode((unsigned char*)data, data_len);
if (!base64_str) {
php_error_docref(NULL, E_WARNING, "Failed to base64 decode the input");
EVP_CIPHER_CTX_free(cipher_ctx);
RETURN_FALSE;
}
data_len = ZSTR_LEN(base64_str);
data = ZSTR_VAL(base64_str);
}
if (php_openssl_cipher_init(cipher_type, cipher_ctx, &mode,
&password, &password_len, &free_password,
&iv, &iv_len, &free_iv, tag, tag_len, options, 0) == FAILURE ||
php_openssl_cipher_update(cipher_type, cipher_ctx, &mode, &outbuf, &outlen,
data, data_len, aad, aad_len, 0) == FAILURE) {
RETVAL_FALSE;
} else if (mode.is_single_run_aead ||
EVP_DecryptFinal(cipher_ctx, (unsigned char *)ZSTR_VAL(outbuf) + outlen, &i)) {
outlen += i;
ZSTR_VAL(outbuf)[outlen] = '\0';
ZSTR_LEN(outbuf) = outlen;
RETVAL_STR(outbuf);
} else {
php_openssl_store_errors();
zend_string_release_ex(outbuf, 0);
RETVAL_FALSE;
}
if (free_password) {
efree(password);
}
if (free_iv) {
efree(iv);
}
if (base64_str) {
zend_string_release_ex(base64_str, 0);
}
EVP_CIPHER_CTX_cleanup(cipher_ctx);
EVP_CIPHER_CTX_free(cipher_ctx);
}
/* }}} */
?有兴趣的可以看看PHP的实现。
PHP有点像是宠溺孩子的妈妈,把啥都干了,那么phper就是妈宝男了,玩笑玩笑。
参考了部分文章:
https://www.cnblogs.com/linuxcat/p/14494630.html
http://tool.chacuo.net/cryptaes
https://blog.csdn.net/Herishwater/article/details/92131547
|