您的位置:首页 > 编程语言 > PHP开发

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

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

【加密规范】:

加密标准:AES

加密算法:CBC

BlockSize:256bit(32byte)

keysize:256(32byte)

padding:pkcs7

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

【pkcs7】

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

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

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

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

【PHP加密】

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

01
/**
02
*
pkcs7补码
03
*
04
*
@paramstring$string明文
05
*
@paramint$blocksizeBlocksize,以byte为单位
06
*
07
*
@returnString
08
*/
09
function
addPkcs7Padding(
$string
,
$blocksize
=
32){
10
$len
=
strlen
(
$string
);
//取得字符串长度
11
$pad
=
$blocksize
-
(
$len
%
$blocksize
);
//取得补码的长度
12
$string
.=
str_repeat
(
chr
(
$pad
),
$pad
);
//用ASCII码为补码长度的字符,
补足最后一段
13
return
$string
;
14
}
15
16
/**
17
*
加密然后base64转码
18
*
19
*
@paramString明文
20
*
@param加密的初始向量(IV的长度必须和Blocksize一样,且加密和解密一定要用相同的IV)
21
*
@param$key密钥
22
*/
23
function
aes256cbcEncrypt(
$str
,
$iv
,
$key
)
{
24
return
base64_encode
(mcrypt_encrypt(MCRYPT_RIJNDAEL_256,
$key
,
addPkcs7Padding(
$str
)
,MCRYPT_MODE_CBC,
$iv
));
25
}
26
27
/**
28
*
除去pkcs7padding
29
*
30
*
@paramString解密后的结果
31
*
32
*
@returnString
33
*/
34
function
stripPkcs7Padding(
$string
){
35
$slast
=
ord(
substr
(
$string
,
-1));
36
$slastc
=
chr
(
$slast
);
37
$pcheck
=
substr
(
$string
,
-
$slast
);
38
if
(preg_match(
"/$slastc{"
.
$slast
.
"}/"
,
$string
)){
39
$string
=
substr
(
$string
,
0,
strlen
(
$string
)-
$slast
);
40
return
$string
;
41
}
else
{
42
return
false;
43
}
44
}
45
46
47
/**
48
*
解密
49
*
50
*
@paramString$encryptedText二进制的密文
51
*
@paramString$iv加密时候的IV
52
*
@paramString$key密钥
53
*
54
*
@returnString
55
*/
56
function
aes256cbcDecrypt(
$encryptedText
,
$iv
,
$key
)
{
57
$encryptedText
=
base64_decode
(
$encryptedText
);
58
return
stripPkcs7Padding(mcrypt_decrypt(MCRYPT_RIJNDAEL_256,
$key
,
$encryptedText
,
MCRYPT_MODE_CBC,
$iv
));
59
}
60
61
$e
=
aes256cbcEncrypt(
"the
dogpassthroughthestreet"
,
'12345678901234561234567890123456'
,
'12345678901234561234567890123456'
);
62
echo
$e
,
"<br>"
;
63
echo
aes256cbcDecrypt(
$e
,
'12345678901234561234567890123456'
,
'12345678901234561234567890123456'
);
【C#加密】

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

01
private
StringAES_encrypt(StringInput,byte[]Iv,byte[]Key)
02
{
03
var
aes=newRijndaelManaged();
04
aes.KeySize
=256;
05
aes.BlockSize
=256;
06
aes.Padding
=PaddingMode.PKCS7;
07
aes.Key
=Key;
08
aes.IV
=Iv;
09
10
var
encrypt=aes.CreateEncryptor(aes.Key,aes.IV);
11
byte[]
xBuff=null;
12
using
(varms=newMemoryStream())
13
{
14
using
(varcs=newCryptoStream(ms,encrypt,CryptoStreamMode.Write))
15
{
16
byte[]
xXml=Encoding.UTF8.GetBytes(Input);
17
cs.Write(xXml,
0,xXml.Length);
18
}
19
20
xBuff
=ms.ToArray();
21
}
22
23
String
Output=Convert.ToBase64String(xBuff);
24
return
Output;
25
}
26
27
private
StringAES_decrypt(StringInput,byte[]Iv,byte[]Key)
28
{
29
RijndaelManaged
aes=newRijndaelManaged();
30
aes.KeySize
=256;
31
aes.BlockSize
=256;
32
aes.Mode
=CipherMode.CBC;
33
aes.Padding
=PaddingMode.PKCS7;
34
aes.Key
=Key;
35
aes.IV
=Iv;
36
37
var
decrypt=aes.CreateDecryptor();
38
byte[]
xBuff=null;
39
using
(varms=newMemoryStream())
40
{
41
using
(varcs=newCryptoStream(ms,decrypt,CryptoStreamMode.Write))
42
{
43
byte[]
xXml=Convert.FromBase64String(Input);
44
cs.Write(xXml,
0,xXml.Length);
45
}
46
47
xBuff
=ms.ToArray();
48
}
49
50
String
Output=Encoding.UTF8.GetString(xBuff);
51
return
Output;
52
}
正文部分到此结束
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: