Home  >  Article  >  php教程  >  AES-CBC加密 以及PHP C#实现

AES-CBC加密 以及PHP C#实现

WBOY
WBOYOriginal
2016-06-06 20:07:291699browse

折腾了好多天, 感谢乔楚大侠的帮忙, 终于搞定了 AES - CBC 加密, 特地将加密部分的东西整理一下, 希望能给后人带来一些帮助 【加密规范】: 加密标准: AES 加密算法: CBC BlockSize:256bit(32byte) keysize : 256 (32byte) padding : pkcs7 AES-CBC是

    折腾了好多天, 感谢乔楚大侠的帮忙, 终于搞定了 AES - CBC 加密, 特地将加密部分的东西整理一下, 希望能给后人带来一些帮助

    【加密规范】:

            加密标准:AES

            加密算法:CBC

            BlockSize:256bit(32byte)

            keysize   :   256 (32byte)

            padding  :   pkcs7


             AES-CBC是一种分段解密的方式,即先把明文分段, 然后再加密, 参数Blocksize 定义每段的大小, 支持 128bit  256 bit , 在分好段之后,最后的一段不一定满一个blocksize, 所以需要先对明文进行补码在加密,pkcs7 的补码方式, 后边会提到。  密钥的长度支持 128 192 和 256.

     【pkcs7】

            pkcs7 的算法其实比较简单, 完全可以自己封装一个函数:

                第一步: 拿到明文的长度 len 和 blocksize (字节) 

                第二部: 算出最后一段需要补码的长度  paddingLen =  len -  text % blocsize

                第三部:  取得 ASCII 码 为补码长度 paddingLen的字符, 用该字符把最后一段填满就OK了, 详情请参见我的PHP代码

     【PHP加密】

             PHP要使用加密的函数, 必须安装 mcrypt 的扩展。

/**
 * pkcs7补码
 *
 * @param string $string  明文
 * @param int $blocksize Blocksize , 以 byte 为单位
 *
 * @return String
 */
function addPkcs7Padding($string, $blocksize = 32) {
    $len = strlen($string); //取得字符串长度
    $pad = $blocksize - ($len % $blocksize); //取得补码的长度
    $string .= str_repeat(chr($pad), $pad); //用ASCII码为补码长度的字符, 补足最后一段
    return $string;
}

/**
 * 加密然后base64转码
 *
 * @param String 明文
 * @param 加密的初始向量(IV的长度必须和Blocksize一样, 且加密和解密一定要用相同的IV)
 * @param $key 密钥
 */
function aes256cbcEncrypt($str, $iv, $key ) {
	return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, addPkcs7Padding($str) , MCRYPT_MODE_CBC, $iv));
}

/**
 * 除去pkcs7 padding
 *
 * @param String 解密后的结果
 *
 * @return String
 */
function stripPkcs7Padding($string){
    $slast = ord(substr($string, -1));
    $slastc = chr($slast);
    $pcheck = substr($string, -$slast);
    if(preg_match("/$slastc{".$slast."}/", $string)){
        $string = substr($string, 0, strlen($string)-$slast);
        return $string;
    } else {
        return false;
    }
}

/**
 * 解密
 *
 * @param String $encryptedText 二进制的密文
 * @param String $iv 加密时候的IV
 * @param String $key 密钥
 *
 * @return String
 */
function aes256cbcDecrypt($encryptedText, $iv, $key) {
	$encryptedText =base64_decode($encryptedText);
	return stripPkcs7Padding(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encryptedText, MCRYPT_MODE_CBC, $iv));
}

$e =  aes256cbcEncrypt("the dog pass through the street", '12345678901234561234567890123456', '12345678901234561234567890123456');
echo $e , "<br>";
echo aes256cbcDecrypt($e, '12345678901234561234567890123456', '12345678901234561234567890123456');

    【C#加密】

        C# 比较爽自带的有 AES-CBC加密的类, 只需要 using System.Security.Cryptography; 就行了

        private String AES_encrypt(String Input, byte[] Iv, byte[] Key)
        {
            var aes = new RijndaelManaged();
            aes.KeySize = 256;
            aes.BlockSize = 256;
            aes.Padding = PaddingMode.PKCS7;
            aes.Key = Key;
            aes.IV = Iv;

            var encrypt = aes.CreateEncryptor(aes.Key, aes.IV);
            byte[] xBuff = null;
            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(ms, encrypt, CryptoStreamMode.Write))
                {
                    byte[] xXml = Encoding.UTF8.GetBytes(Input);
                    cs.Write(xXml, 0, xXml.Length);
                }

                xBuff = ms.ToArray();
            }

            String Output = Convert.ToBase64String(xBuff);
            return Output;
        }

        private String AES_decrypt(String Input, byte[] Iv, byte[] Key)
        {
            RijndaelManaged aes = new RijndaelManaged();
            aes.KeySize = 256;
            aes.BlockSize = 256;
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;
            aes.Key = Key;
            aes.IV = Iv;

            var decrypt = aes.CreateDecryptor();
            byte[] xBuff = null;
            using (var ms = new MemoryStream())
            {
                using (var cs = new CryptoStream(ms, decrypt, CryptoStreamMode.Write))
                {
                    byte[] xXml = Convert.FromBase64String(Input);
                    cs.Write(xXml, 0, xXml.Length);
                }

                xBuff = ms.ToArray();
            }

            String Output = Encoding.UTF8.GetString(xBuff);
            return Output;
        }

声明: 本文采用 CC BY-NC-SA 3.0 协议进行授权

转载请注明来源:小景的博客

本文链接地址:http://www.phpv5.com/blog/encrypt-aes-cbc

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn