python实现AES-128-CBC算法与php实现的对比。重点注意python进行base64加解码,而PHP封装过度,帮你实现了这部分

18 篇文章 0 订阅

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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扬子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值