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