none
DESCryptoServiceProvider解密问题 RRS feed

  • 问题

  • 我使用DESCryptoServiceProvider对一个字符进行加密解密
    加密可以了就是解密
    会出现错
    1、Base-64字符数组无效长度
    2、要解密的数据长度无效
    这两个错误随着加密解密的字符个数而变化
    如:长度为1时候出现错误1,为2是出现错误2(只是例如)
    字符串数组转实验了很多无效
    如:
    byte[] buffer = Convert.FromBase64String(_Str);
    byte[] buffer = Encoding.Unicode.GetBytes(_Str)
    还有就是不支持中文,密码长度必须为8
    代码如下:
    using System;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;
    
    namespace Cryptography
    {
        /// <summary>
        /// DES 密码
        /// </summary>
        public static class DESCryptoObject 
        {
            /// <summary>
            /// 默认密钥
            /// </summary>
            pr_ivate static readonly byte[] __key=new byte[]{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
            /// <summary>
            /// 默认初始化响亮
            /// </summary>
            pr_ivate static readonly byte[] __iv = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
            
            public static string ToEncrypt(this string _str){
                return _encrypt(_str, __key, __iv);
            }
            
            public static string Encrypt(string _Str)
            {
                return _encrypt(_Str, __key, __iv);
            }
            
            public static string Encrypt(string _Str, string _key)
            {
    
                return _encrypt(_Str, Encoding.ASCII.GetBytes(_key), __iv);
            }        public static string Encrypt(string _Str, byte[] _key)
            {
                return _encrypt(_Str, _key, __iv);
            }
           
            public static string Encrypt(string _Str, byte[] _key, byte[] _iv)
            {
                return _encrypt(_Str,_key,_iv);
            }
            pr_ivate static string _encrypt(string _Str, byte[] _key, byte[] _iv)
            {
                string nStr = string.Empty;//加密后字符串
                byte[] _key_64 = _key;//密钥
                byte[] _iv_64 = _iv;//初始化向量
    
                if (_Str.Length > 0)//加密字符串长度不可为0
                {
                    //初始化加密对象
                    using (var cryptoProvider = new DESCryptoServiceProvider())
                    {
                        
                        var ms = new MemoryStream();
                        var cs = new Crypt_Stream(ms,cryptoProvider.CreateEncryptor(_key_64,_iv_64),Crypt_StreamMode.Write);
                        var d = Encoding.Unicode.GetBytes(_Str);
                        cs.Write(d,0,d.Length);
                        cs.FlushFinalBlock();
                        var buffer = ms.ToArray();
                        nStr = Convert.ToBase64String(buffer,0,(int)ms.Length);
                        //关闭资源
                        cs.Close();
                        ms.Close();
                    }
                }
                return nStr;
            }
    
            public static string ToDecrypt(this string _Str)
            {
                return _decrypt(_Str, __key, __iv);
            }
            
            public static string Decrypt(string _Str)
            {
                return _decrypt(_Str, __key, __iv);
            }
    
            public static string Decrypt(string _Str, string _key)
            {
                return _decrypt(_Str, Encoding.ASCII.GetBytes(_key), __iv);
            }
    
            public static string Decrypt(string _Str, byte[] _key)
            {
                return _decrypt(_Str, _key, __iv);
            }
    
            public static string Decrypt(string _Str, byte[] _key, byte[] _iv)
            {
                return _decrypt(_Str,_key,_iv);
            }
            pr_ivate static string _decrypt(string _Str, byte[] _key, byte[] _iv)
            {
                string nStr = string.Empty;//解密后内容
                byte[] _key_64 = _key;//密钥
                byte[] _iv_64 = _iv;//初始化向量
                if (_Str.Length > 0)//解密内容长度不可以是0
                {
                    //初始化加密对象
                    using (var cryptoProvider = new DESCryptoServiceProvider())
                    {
                        
                        //byte[] buffer = Convert.FromBase64String(_Str);
                        byte[] buffer = Encoding.Unicode.GetBytes(_Str);
                        var ms = new MemoryStream();
                        var cs = new Crypt_Stream(
                            ms,cryptoProvider.CreateDecryptor(_key_64,_iv_64),
                                  Crypt_StreamMode.Write);
                        cs.Write(buffer,0,buffer.Length);
                        cs.FlushFinalBlock();
                        buffer = ms.ToArray();
                        nStr = Encoding.Unicode.GetString(buffer);
                        //关闭资源
                        cs.Close();
                        ms.Close();
                    }
                }
                return nStr;
            }
        }
    }
    2009年3月31日 8:47

答案

  • 你好!
         密钥必须是8个字节,而初始化向量也需要同样的长度,我写了一个例子,希望对你有帮助:
     static
     void
     Main(string
    [] args)
            {
                string
     sMsg = "The message to encrypt!"
    ;
                string
     sEnc, sDec;
                DESCryptoServiceProvider des = new
     DESCryptoServiceProvider();
                Encoding utf = new
     UTF8Encoding();
    
                byte
    [] key = utf.GetBytes("12345678"
    );
                byte
    [] iv = new
     byte
    [] { 1, 2, 3, 4, 5, 6, 7, 8 };
    
                ICryptoTransform encryptor = des.CreateEncryptor(key, iv);
                ICryptoTransform decryptor = des.CreateDecryptor(key, iv);
                {
                    byte
    [] bMsg = utf.GetBytes(sMsg);
                    byte
    [] bEnc = encryptor.TransformFinalBlock(bMsg, 0, bMsg.Length);
                    sEnc = Convert.ToBase64String(bEnc);
                }
                {
                    byte
    [] bEnc = Convert.FromBase64String(sEnc);
                    byte
    [] bDec = decryptor.TransformFinalBlock(bEnc, 0, bEnc.Length);
    
                    sDec = utf.GetString(bDec);
                }
    
                Console.WriteLine("Message : "
     + sMsg);
                Console.WriteLine("Encrypted : "
     + sEnc);
                Console.WriteLine("Decrypted : "
     + sDec);
            }
    

    周雪峰
    2009年3月31日 11:32
    版主

全部回复

  • 你好!
         密钥必须是8个字节,而初始化向量也需要同样的长度,我写了一个例子,希望对你有帮助:
     static
     void
     Main(string
    [] args)
            {
                string
     sMsg = "The message to encrypt!"
    ;
                string
     sEnc, sDec;
                DESCryptoServiceProvider des = new
     DESCryptoServiceProvider();
                Encoding utf = new
     UTF8Encoding();
    
                byte
    [] key = utf.GetBytes("12345678"
    );
                byte
    [] iv = new
     byte
    [] { 1, 2, 3, 4, 5, 6, 7, 8 };
    
                ICryptoTransform encryptor = des.CreateEncryptor(key, iv);
                ICryptoTransform decryptor = des.CreateDecryptor(key, iv);
                {
                    byte
    [] bMsg = utf.GetBytes(sMsg);
                    byte
    [] bEnc = encryptor.TransformFinalBlock(bMsg, 0, bMsg.Length);
                    sEnc = Convert.ToBase64String(bEnc);
                }
                {
                    byte
    [] bEnc = Convert.FromBase64String(sEnc);
                    byte
    [] bDec = decryptor.TransformFinalBlock(bEnc, 0, bEnc.Length);
    
                    sDec = utf.GetString(bDec);
                }
    
                Console.WriteLine("Message : "
     + sMsg);
                Console.WriteLine("Encrypted : "
     + sEnc);
                Console.WriteLine("Decrypted : "
     + sDec);
            }
    

    周雪峰
    2009年3月31日 11:32
    版主
  • 我使用初始化向量为8个字节时候也会出现上述问题,使用非8季节初始化向量加密也可以成功
    使用加密方法都没问题,就是解密问题

    2009年4月1日 4:09
  • 还有使用
    Convert.FromBase64String(_Str);
    Encoding.Unicode.GetBytes(_Str);
    或者其他任意一种都不行!他们之间是不是不光是编码不同吧
    2009年4月1日 4:13