这段时间搞了个接口加密的重写,感觉信息的加密在数据传输中还是比较重要的,小小的研究了下,做点笔记,以备查阅。
在信息加密的过程中,有两个最为重要的问题,安全与效率,什么是安全的关键,秘钥!所以在加密过程中使用了CA加密来保证加密的安全,所谓的CA加密就是由证书机构提供秘钥的RSA算法,秘钥长度为1024位,RSA加密算法的原理就不赘述了,可以简单的理解为解密是加密的数学逆运算,但是通过数学手段的构造,可以使加密与解密的秘钥不同,即公钥加密,私钥解密,最大程度的保护了信息安全。在C#中使用RSA加密可以使用系统封装好的RSACryptoServiceProvider类来实现加密,分为以下几步:
1.获取加密公钥的路径
string fileName = @"E:BlogDemoDESDemoDESDemoCAPublicKey.cer";
2.根据公钥创建证书中心类,从而从公钥的xml中获取加密秘钥
X509Certificate2 objx5092; if (string.IsNullOrEmpty(password)) objx5092 = new X509Certificate2(fileName); else objx5092 = new X509Certificate2(fileName, password);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(objx5092.PublicKey.Key.ToXmlString(false));
3.需要注意的一点是加密块最大长度限制,如果加密数据的长度超过秘钥长度/8-11,会引发长度不正确的异常,所以进行数据的分块加密,这是由于c#封装的类库中使用的是RSA PKCS1padding 填充模式,密钥长度为1024位,那么输出的密文块长度为128个字节,输入的明文块长度为127-10,即输入的明文块最大是117位,如果输入的明文块小于117位,比如输入的明文块长度为64位,那么会对这个明文块进行补位,在明文块前添加一位的0x02字节(代表公钥加密)然后后面的52位为随机的字节,在补位的最后一位,{即52(117-64-1),从零开始的},添加一位的字节0x00,在补位的在补位的后面添加实际的明文块
int MaxBlockSize = rsa.KeySize / 8 - 11; //正常长度 if (data.Length <= MaxBlockSize) { byte[] hashvalueEcy = rsa.Encrypt(data, false); //加密 return Convert.ToBase64String(hashvalueEcy); } //长度超过正常值 else { using (MemoryStream PlaiStream = new MemoryStream(data)) using (MemoryStream CrypStream = new MemoryStream()) { Byte[] Buffer = new Byte[MaxBlockSize]; int BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize); while (BlockSize > 0) { Byte[] ToEncrypt = new Byte[BlockSize]; Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize); Byte[] Cryptograph = rsa.Encrypt(ToEncrypt, false); CrypStream.Write(Cryptograph, 0, Cryptograph.Length); BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize); } return Convert.ToBase64String(CrypStream.ToArray(), Base64FormattingOptions.None); } }
在RSA加密的过程中需要进行繁杂的数学计算从而进行数据的加密解密,如果数据量很大的话,效率就会十分低下,所以RSA加密通常用来验证签名或者加密秘钥。而加密运算效率较高的就是对称加密,在这里我们使用DES加密,DES加密中只涉及到四个变量,原文,秘钥,加密向量,密文,原理简单来说是通过秘钥对数据分块进行位移变化达到加密解密的效果。默认的加密运算模式为CBC,为密码块链模式,每个加密块都与前一段加密数据相关联,防止了词典攻击,但数据独立性较差;DES的填充模式为PaddingMode.PKCS7,即当明文的加密块数据小于块长度时,自动填充,达到加密长度;加密向量的作用是防止在明文中重复的内容带入密文中,加密向量会在每块文字段都会依次加上一段值,从而密文中就不会出现重读的段落。
DES算法加密代码示例如下所示:
byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8)); byte[] keyIV = Keys; byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString); DESCryptoServiceProvider provider = new DESCryptoServiceProvider(); MemoryStream mStream = new MemoryStream(); CryptoStream cStream = new CryptoStream(mStream, provider.CreateEncryptor(keyBytes, keyIV), CryptoStreamMode.Write); cStream.Write(inputByteArray, 0, inputByteArray.Length); cStream.FlushFinalBlock(); return Convert.ToBase64String(mStream.ToArray());
所有,综上所述,使用DES加密算法加密明文,使用RSA算法加密秘钥,是效率与安全取得平衡的一个较好的处理方法。
csdn完整示例资源下载地址:http://download.csdn.net/detail/u013407099/9645037
(出于信息保护,CA加密的公钥与私钥需要自己从IIS生成)