原问题1:
加密时是直接写入文件的,解密时是一边读加密后的文件,一边解。对于有的字符串就对,有的就不对,我怀疑那个DES加密的类有问题。

public static void DesEncrypt(Stream inStream,Stream outStream,byte[] desKey,byte[] desIV)
...{
        DES des=new DESCryptoServiceProvider();
        CryptoStream cs=new CryptoStream(outStream,des.CreateEncryptor(desKey,desIV),CryptoStreamMode.Write);
        byte[] buf=new byte[1024];
        int len=0;
        while ((len=inStream.Read(buf,0,buf.Length))>0)
        ...{
                cs.Write(buf,0,len);
        }
        cs.Close();
}

public static void DesDeEncrypt(Stream inStream,Stream outStream,byte[] desKey,byte[] desIV)
...{
        DES des=new DESCryptoServiceProvider();
        CryptoStream cs=new CryptoStream(inStream,des.CreateDecryptor(desKey,desIV),CryptoStreamMode.Read);
        byte[] buf=new byte[1024];
        int len=0;
        while ((len=cs.Read(buf,0,buf.Length))>0)
        ...{
                outStream.Write(buf,0,len);
        }
}

原问题2:
发现加密类RijndaelManaged的问题,根据MSDN的这个例子发现的问题,例子源码(VS2003)
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfSystemSecurityCryptographyRijndaelManagedClassTopic.htm
问题描述:在最后的Console.WriteLine("Round Trip: {0}", roundtrip );这行代码后面追加下面的代码
Console.WriteLine(original.Length == roundtrip.Length);
运行一下看看,按照正常想法应该是解密后的内容应该与原文完全相同,输出True,但是却输出False。

 这两个问题都差不多,都是因为不了解对称加密(AES/DES等)的加密原理,而误认为.net framework的加密算法有问题。

AES/DES都是块式加密的(块的大小等于密钥的大小)。对于AES算法,其密钥大小为128bit(16byte),故每块16byte,在加密之前要对加密数据进行填充(例如:如果要用AES算法加密100byte的数据,则填充成112byte构成16的倍数,加密之后的数据大小为112byte;如果要加密112byte,则要另外填充16byte,构成128byte,加密之后的数据大小为128byte)。现在回过头来看看问题2,我们将MSDN中的代码改成下面这样则可以返回true了:
fromEncrypt = new byte[toEncrypt.Length];//MSDN中使用的是encrypted.Length;
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
这是因为按照MSDN的示例执行加密后,由于填充的缘故,encrypted的长度要比toEncrypt大,而MSDN的示例中是以encrypted的长度来设定fromEncrypt的长度,故解密之后fromEncrypt后面有一段是空的,得到的解密后字符串roundtrip中的后面有一截是以'\0'进行填充了,故长度不一样了。而使用toEncrypt.Length来设定fromEncrypt的长度,则申请的空间刚刚够用,不用填充。

下面再来看看第一个问题:每次取1024byte进行加密,加密时系统会自动填充8个byte(DES的密钥长度为64bit),加密后得到1024+8byte的数据,所以你解密的时候要每次取1024+8byte进行解密。而对于加密前文件大小小于或等于1016byte的文件,加密后大小小于或等于1024byte,故循环只执行一次,按照问题中的解密代码可以解密成功,而对于再大一点或更大的文件,则必然解密失败,所以才出现问题中的“对于有的字符串就对,有的就不对”。修正后的测试代码如下:

DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.GenerateKey();
des.GenerateIV();
FileStream fs1 = new FileStream("自然.mp3", FileMode.Open, FileAccess.Read);
FileStream fs2 = new FileStream("Encrypted.mp3", FileMode.OpenOrCreate, FileAccess.Write);

//加密
CryptoStream csEnCrypt=new CryptoStream(fs2,des.CreateEncryptor(des.Key,des.IV),CryptoStreamMode.Write);
byte[] buf=new byte[1024];
int len = 0;
while ((len=fs1.Read(buf,0,buf.Length))>0)
...{                
   csEnCrypt.Write(buf,0,len);
   csEnCrypt.Flush();
   Console.WriteLine("Encrypt: " + len.ToString());
}
Console.ReadLine();
Console.WriteLine(" ");
csEnCrypt.Close();
fs1.Close();
fs2.Close();

//解密
FileStream fs4 = new FileStream("Encrypted.mp3", FileMode.OpenOrCreate, FileAccess.Read);
FileStream fs3 = new FileStream("Decrypted.mp3", FileMode.OpenOrCreate, FileAccess.Write);
CryptoStream csDecrypt = new CryptoStream(fs4, des.CreateDecryptor(des.Key, des.IV), CryptoStreamMode.Read);
byte[] buf2 = new byte[1024+8];
while ((len = csDecrypt.Read(buf2, 0, buf2.Length)) > 0)
...{
    Console.WriteLine("Decrypt: " + len.ToString());
    fs3.Write(buf2, 0,len);
    fs3.Flush();
}
csDecrypt.Close();
fs3.Close();//可以正常播放了
fs4.Close();

补充 :.Net数据安全
1.填充模式(Padding Mode): None,PKCS7,Zeros.

2.加密模式(Cipher Mode):CBC,CFB,CTS,ECB,OFB.

3.对称加密:
  DESCryptoServiceProvider:     Key- 64bit          IV- 64bit
  RC2CryptoServiceProvider:     Key-128bit          IV- 64bit
  DijndaeManaged(AES)     :     Key-256/128/192bit  IV-128bit
  TripDESCryptoServiceProvider: key-192bit          IV- 64bit
  CreateDecryptor()构造解密器,CreateEncryptor()构造加密器。

4.非对称加密:
  DSA:KeySize=1024bit
      DSASignatrueFommatter类:创建数字签名;
      DSASignatrueDefommatter类:验证数字签名;
  RSA:KeySize=1024bit
      加密:RSA.Encrypt(byte[] DataEncrypt,bool Padding)
      解密:RSA.Decrypt(byte[] DataEncrypt,bool Padding)
      导出/导入密钥:RSA.ToXmlString(bool)/RSA.FromXml(string)
      签名/验证:RSA.SignData()/RSA.VerifyData()

5.消息摘要:
  HMACSHA1
  MACTripleDES
  MD5CryptoServiceProvider(128bit)
  SHA1Managed(160bit)
  SHA256Managed(256bit)
  SHA384Managed(384bit)
  SHA512Managed(512bit)

参考文献:
[1] MSDN
[2] 《应用密码学》Bruce Schneier[著],吴世忠等[译]

使用对称加/解密时,要注意考虑填充相关推荐

  1. Openssl 对称加解密函数 - EVP_Cipher、EVP_Encrypt、EVP_Decryp 系列

    实验环境:openssl 1.1.1k EVP_CipherInit_ex().EVP_CipherUpdate() 和 EVP_CipherFinal_ex() 是可用于解密或加密的函数.执行的操作 ...

  2. [crypto]-02-非对称加解密RSA原理概念详解

    说明:本文使用的数据来自网络,重复的太多了,也不知道哪篇是原创. 算法原理介绍 step 说明 描述 备注 1 找出质数 P .Q - 2 计算公共模数 N = P * Q - 3 欧拉函数 φ(N) ...

  3. DESUtils 加解密时 Given final block not properly padded bug小记

    事情的经过是这个样子的...... 先说说问题是怎么出现的.根据客户需求,需要完成一个一键登录的功能,于是我的项目中就诞生了DesUtil,但是经过上百次用户测试,发现有一个用户登录就一直报错!难道又 ...

  4. 数据加解密时Base64异常:Illegal base64 character 3f

    现象 用base64工具类对中文进行处理时出现异常,在数据加解密场景中经常使用 java.lang.IllegalArgumentException: Illegal base64 character ...

  5. 某付宝APP之某加油小程序对称加解密算法解析

    前言 前几天发了一个某付宝小程序的sign参数md5加密拿到明文参数的帖子- 又发现一个别的小程序,好像是用的对称加密,耐不住好奇心,就试了试-结果成功实现了加解密的操作.遂发帖记录一下. 工具 fi ...

  6. Java 进行 RSA 加解密时不得不考虑到的那些事儿

    1. 加密的系统不要具备解密的功能,否则 RSA 可能不太合适 公钥加密,私钥解密.加密的系统和解密的系统分开部署,加密的系统不应该同时具备解密的功能,这样即使黑客攻破了加密系统,他拿到的也只是一堆无 ...

  7. java C# objective-c AES对称加解密

    1 /** 2 * AES加解密 3 */ 4 public class AESHelper { 5 final static String AES_KEY = "43hr8fhu34b58 ...

  8. android byte转string_高性能AES256对称加解密,兼容Java、IOS、Android

    最近在设计一个给IOS和Android提供接口的项目框架,在接口安全上准备使用常规的加密技术,确保在非法访问接口的情况下拿到的数据一时半会也没用. 查了相关的资料,用的最多的几种加密算法,DES.AE ...

  9. Java使用PBE算法进行对称加解密最简入门和示例

    PBE 算法 PBE( Password Based Encryption, 基于口密加密).PBE是一种基于口令的加密算法, 采用随机数杂凑(盐)多重加密方法保证数据安全性. PBE算法并没有真正构 ...

最新文章

  1. 高级转录组分析和R数据可视化第11期(课程推迟,可先报名,时间另行告知)
  2. 10秒完成Linux系统pip在线安装
  3. html文档表示表格的标记,【单选题】在HTML文档中用于表示表格的标记对是( )...
  4. python赋值语句的一般格式为_[零基础学Python]赋值,简单也不简单
  5. ajax不支持post,AJAX不能正确发送POST变量
  6. python学习指令_由Python到深度学习入门之常用命令
  7. 无心剑英译罗兰《境由心造》
  8. 鸿蒙系统年底发布?华为人员看到这个山寨网站笑了
  9. 租车信息系统数据库设计(2)
  10. 怎么写出一个Activity
  11. /var/run/yum.pid 已被锁定,PID 为 XXXX 的另一个程序正在运行。
  12. Hadoop入门到精通(不断更新中。。。。)
  13. 保险公司智能运营系统——软件需求规格说明
  14. PR更改视频画布大小。PR剪裁视频。PR导出视频时的适应视屏大小都是啥意思啊?
  15. 将Android手机无线连接到Ubuntu实现唱跳Rap
  16. 【C语言】输入一个整数n,求它的位数以及各位数字之和。例如,123的位数是3,各位数字之和是6。
  17. 最新服务器cpu14纳米,英特尔CPU路线图 14nm活力不减 7nm不远了
  18. PB实现国密SM2/SM3/SM4算法(DLL方式)
  19. Python|简易银行ATM程序制作
  20. uboot.lds 链接文件分析

热门文章

  1. 虚拟化的适用范围和适用场景,服务器虚拟化架构和功能
  2. 轴承热处理,你了解吗?
  3. 全自动一键签到v1.0小工具
  4. 仿百度文库html5源码,JS实现仿百度文库评分功能
  5. 拍拍贷用户及还款数据分析案例
  6. 如何成为二八定律中的“20%”
  7. 基于iBeacon的智慧旅游解决方案
  8. pymongo学习笔记
  9. Word使用基本技巧汇总
  10. PythonCSV文件操作小结