关闭

解决“Base-64字符数组的无效长度” 的问题

标签: string加密解密exceptionbytenull
34730人阅读 评论(4) 收藏 举报

这两天做一个视频分享的模块,有一个功能是解析地址栏中的加密字符串.实际使用过程中发现了"Base-64字符数组的无效长度"的问题。

后来分析才知道是由于地址栏中的字符"+"没有正确解析导致的。

 

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Text;
using System.Security.Cryptography;

namespace EtahTeachVideo.Media
{
    public partial class SharedVideo : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
               
                if (Request.QueryString["IDTM"] != null)
                {
                    string strRequest = Request.QueryString["IDTM"];
                    strRequest = strRequest.Replace(' ', '+'); //注意,IDTM=JI7W/IZIoZadVU+dCqd4WSLFVJb3mK3i 中的"+"通过地址栏传过来时,后台会解析为空格. 最好的做法是 使用String.Replace("+", "%2B")先将空格编码,然后再作为参数传给另一页面传递,这样页面在提取参数时才会将“%2B”解码为加号.但这儿为了简化,将空格直接还原为"+"。
                    Encrypt enr = new Encrypt ();
                    string strEncryptCharacter = enr.DecryptString(strRequest);
                    if (strEncryptCharacter != null && strEncryptCharacter.IndexOf("|") > 1)
                    {

                        string strMediaID = strEncryptCharacter.Split('|')[0];
                        string strGenerateTime = strEncryptCharacter.Split('|')[1];                       
                        DateTime dtGeneateTime = DateTime.Parse(strGenerateTime);
                        TimeSpan spn = DateTime.Now.Subtract(dtGeneateTime);
                        if (spn.TotalSeconds > 24 * 60 * 60)
                        {
                            //超过一天的情况
                            Response.Write("您请求的视频已经过期,请联系管理员获取新的地址.");
                            return;
                        }
                        int nMediaID = int.Parse(strMediaID);
                        string strJs = @"<script type='text/javascript'> " +
                                           "window.moveTo((window.screen.width-1010)/2,(window.screen.height-685)/2);" +
                                           "window.resizeTo(1010,685);" +
                                           "window.showModalDialog('PlayerVod.htm?Query=" + strMediaID + "','','dialogWidth=1010px;dialogHeight=685px;status=no;scroll=no;');" +
                                           "window.opener= null;window.open('','_self'); window.close();" + //解决关闭窗口的提示ie7下必须加window.open('','_self')才有效.
                                        "</script>";
                        ClientScript.RegisterClientScriptBlock(this.GetType(), "key", strJs);
                    }
                    else
                    {
                        Response.Write("请求的地址有误.");
                        return;
                    }                  
                }
                else
                {
                    Response.Write("您无权查看该网页.");     
                }
        }      
    }

    /// <summary>
    /// 本类完成对字符串的加密和解密。
    /// 通过DES对称加密算法,完成对字符串的加密和解密操作。
    /// </summary>
    public class Encrypt
    {
        private SymmetricAlgorithm mCSP;
        private const string CIV = "kXwL7X2+fgM=";//密钥
        private const string CKEY = "FwGQWRRgKCI=";//初始化向量

        public Encrypt()
        {
            mCSP = new DESCryptoServiceProvider();
        }

        public string EncryptString(string Value)
        {
            ICryptoTransform ct;
            MemoryStream ms;
            CryptoStream cs;
            byte[] byt;

            ct = mCSP.CreateEncryptor(Convert.FromBase64String(CKEY), Convert.FromBase64String(CIV));

            byt = Encoding.UTF8.GetBytes(Value);

            ms = new MemoryStream();
            cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
            cs.Write(byt, 0, byt.Length);
            cs.FlushFinalBlock();

            cs.Close();

            return Convert.ToBase64String(ms.ToArray());
        }

        public string DecryptString(string Value)
        {
            ICryptoTransform ct;
            MemoryStream ms;
            CryptoStream cs;
            byte[] byt;

            try
            {
                ct = mCSP.CreateDecryptor(Convert.FromBase64String(CKEY), Convert.FromBase64String(CIV));


                byt = Convert.FromBase64String(Value);

                ms = new MemoryStream();
                cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
                cs.Write(byt, 0, byt.Length);
                cs.FlushFinalBlock();

                cs.Close();

                return Encoding.UTF8.GetString(ms.ToArray());
            }
            catch(Exception ex)
            {
                return null;
            }
        }

    }

 


}

 

 

 

//参考

 

DES解密时“Base-64字符数组的无效长度”
问题是 在页面传送的时候加密了 ,然后解密出来就抛出异常  跟踪发现是 ++ 在解析REQUEST的时候变成了空格

解决办法

使用String.Replace("+", "%2B")先将空格编码,然后再作为参数传给另一页面传递,这样页面在提取参数时才会将“%2B”解码为加号

下面是一个相关的知识

在使用Convert.ToBase64String()对字符串进行Base64编码时,注意的几点:
   例:string s = "Hello";
      byte[] bytes = Convert.FromBase64String(s);
以上代码在运行时会抛出FormatException异常.提示为:Base-64字符数组的无效长度

原因:
当Convert.FromBase64String方法的参数s的长度小于4或不是4的偶数倍时,将会抛出FormatException。
  
   例:
       Convert.FromBase64String("Hell");      // Normal.
       Convert.FromBase64String("Hell ");     // Normal.(忽略空格)
       Convert.FromBase64String("Hello!");     // throw FormatException.
       Convert.FromBase64String("Hello Net"); // Normal.(忽略空格)

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/swort_177/archive/2008/12/15/3522293.aspx

1
0

猜你在找
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:153878次
    • 积分:1591
    • 等级:
    • 排名:千里之外
    • 原创:11篇
    • 转载:48篇
    • 译文:0篇
    • 评论:20条
    文章分类
    最新评论