折腾了好多天, 感谢乔楚大侠的帮忙, 终于搞定了 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