zoukankan      html  css  js  c++  java
  • .net加密解密

    加密与解密概述

    加密与解密属于数据安全的范畴。在消息传输时,通过对消息进行特殊编码(加密),建立一种安全的交流方式,使得只有发送者所期望的接收者能够理解 (解密)。这里我们定义一个场景:发送方,接收方,第三方,发送方要将信息发送给接收方,二第三方想要截取并篡改消息,然后在转发给接收方。要称得上是安 全的交流方式,需要满足下面的3个条件:

    1. 完整性,消息的接收方可以确定消息在传输过程中没有被篡改过,即消息是完好无损。
    2. 保密性,第三方无法解密发送的消息(第三方可以获取传输的消息)。
    3. 可认证性,即接收方可以知道消息是由谁发送的。

    下面将列出几种常用的技术,看看是否符合上面的3个条件。

    散列运算

    散列(英语:Hashing)是电脑科学中一种对资料的处理方法,通过某种特定的函数/算法(称为散列函数/算法)将要检索的项与用来检索的索引 (称为散列,或者散列值)关联起来,生成一种便于搜索的数据结构(称为散列表)。也译为散列。旧译哈希(误以为是人名而采用了音译)。它也常用作一种资讯 安全的实作方法,由一串资料中经过散列算法(Hashing algorithms)计算出来的资料指纹(data fingerprint),经常用来识别档案与资料是否有被窜改,以保证档案与资料确实是由原创者所提供。
    如今,散列算法也被用来加密存在数据库 中的密码(password)字串,由于散列算法所计算出来的散列值(Hash Value)具有不可逆(无法逆向演算回原本的数值)的性质,因此可有效的保护密码,我公司内的Web管理系统存储的密码字符串就是散列运算的摘要,确实 很实用。

    散列运算具有以下3个特点:

    1. 散列运算是不可逆的(加密是单向的)。
    2. 任何两个不相同文件的摘要是不同的。
    3. 不论原始消息大小如何,同一种散列算法得到的摘要的长度是固定的。

    常见的散列运算如下图所示:

    image

    由此可见散列算法只能满足完整性的条件。

    对称加密

    对称密钥加密(英语:Symmetric-key algorithm)又称为对称加密、私钥加密、共享密钥加密,是密码学中的一类加密算法。这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单 地相互推算的密钥。实务上,这组密钥成为在两个或多个成员间的共同秘密,以便维持专属的通讯联系。与公开密钥加密相比,要求双方取得相同的密钥是对称密钥 加密的主要缺点之一。

    常见的对称加密算法有DES、3DES、AES、Blowfish、IDEA、RC5、RC6。

    对称加密流程如下:

    1. 发送方和接收方吃有相同的密钥并严格保密。
    2. 发送方使用密钥对消息进行加密,然后发送消息。
    3. 接收方接收到消息使用同样能够的密钥进行解密。
    4. 在这一过程中第三方截取到消息,但得到的只是一堆乱码。

    由此可见,对称加密可以解决保密的问题,但是要确保第三方没有非法获取到密钥。

    非对称加密

    非对称加密(asymmetric cryptography),又称为公开密钥加密(英语:public-key cryptography),在这种密码学方法中,需要一对密钥,一是个私人密钥,另一个则是公开密钥。这两个密钥是数学相关,用某用户密钥加密后所得的 信息,只能用该用户的解密密钥才能解密。如果知道了其中一个,并不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个的秘密性质。 称公开的密钥为公钥;不公开的密钥为私钥。
    如果加密密钥是公开的,这用于客户给私钥所有者上传加密的数据,这被称作为公开密钥加密(狭义)。例如,网络银行的客户发给银行网站的账户操作的加密数据。

    如果解密密钥是公开的,用私钥加密的信息,可以用公钥对其解密,用于客户验证持有私钥一方发布的数据或文件是完整准确的,接收者由此可知这条信息确 实来自于拥有私钥的某人,这被称作数字签名,公钥的形式就是数字证书。例如,从网上下载的安装程序,一般都带有程序制作者的数字签名,可以证明该程序的确 是该作者(公司)发布的而不是第三方伪造的且未被篡改过(身份认证/验证)。

    常见的公钥加密算法有: RSA、ElGamal、背包算法、Rabin(RSA的特例)、迪菲-赫尔曼密钥交换协议中的公钥加密算法、椭圆曲线加密算法(英语:Elliptic Curve Cryptography, ECC)。使用最广泛的是RSA算法(由发明者Rivest、Shmir和Adleman姓氏首字母缩写而来)是著名的公开金钥加密算法,ElGamal 是另一种常用的非对称加密算法。

    现在假设这种加密方式只使用一组密钥对,根据使用发送方还是接收方的密钥对又可分为加密模式和认证模式。

    加密模式下,由消息的接收方发布公钥,持有私钥。基本步骤如下所示:

    1. 接收方公布自己的公钥,任何人都可以获得。
    2. 发送方使用上述公钥对消息进行加密,然后发送。
    3. 接收方使用自己的私钥对消息进行解密。

    可以看出非对称加密的加密模式可以解决保密性问题。

    认证模式下,由消息的发送方发布公钥,持有私钥。基本步骤如下所示:

    1. 发送方公布自己的公钥,任何人都可以获得。
    2. 发送方使用自己的私钥对消息进行加密,然后发送。
    3. 接收方使用发送方的私钥对消息进行解密。

    可以看出非对称加密的加密模式可以解决认证性问题。

    得出结论

    上面的技术单一使用无法全部满足完整、保密和认证的3个条件,但是通过组合使用的方式就可以达到目的了。比如说数字签名就是在上面的认证模式加上了散列运算。

    加密解密类(苏飞论坛所有)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    /// <summary>
    /// 类说明:Assistant
    /// 编 码 人:苏飞
    /// 联系方式:361983679 
    /// </summary>
    using System;
    using System.Text;
    using System.Security.Cryptography;
    using System.IO;
    using System.Text.RegularExpressions;
    using System.Collections;
     
    namespace DotNet.Utilities
    {
        /// <summary>
        /// MySecurity(安全类) 的摘要说明。
        /// </summary>
        public class MySecurity
        {
            /// <summary>
            /// 初始化安全类
            /// </summary>
            public MySecurity()
            {
                ///默认密码
                key = "0123456789";
            }
            private string key; //默认密钥
     
            private byte[] sKey;
            private byte[] sIV;
     
            #region 加密字符串
            /// <summary>
            /// 加密字符串
            /// </summary>
            /// <param name="inputStr">输入字符串</param>
            /// <param name="keyStr">密码,可以为“”</param>
            /// <returns>输出加密后字符串</returns>
            static public string SEncryptString(string inputStr, string keyStr)
            {
                MySecurity ws = new MySecurity();
                return ws.EncryptString(inputStr, keyStr);
            }
            /// <summary>
            /// 加密字符串
            /// </summary>
            /// <param name="inputStr">输入字符串</param>
            /// <param name="keyStr">密码,可以为“”</param>
            /// <returns>输出加密后字符串</returns>
            public string EncryptString(string inputStr, string keyStr)
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                if (keyStr == "")
                    keyStr = key;
                byte[] inputByteArray = Encoding.Default.GetBytes(inputStr);
                byte[] keyByteArray = Encoding.Default.GetBytes(keyStr);
                SHA1 ha = new SHA1Managed();
                byte[] hb = ha.ComputeHash(keyByteArray);
                sKey = new byte[8];
                sIV = new byte[8];
                for (int i = 0; i < 8; i++)
                    sKey[i] = hb[i];
                for (int i = 8; i < 16; i++)
                    sIV[i - 8] = hb[i];
                des.Key = sKey;
                des.IV = sIV;
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                StringBuilder ret = new StringBuilder();
                foreach (byte b in ms.ToArray())
                {
                    ret.AppendFormat("{0:X2}", b);
                }
                cs.Close();
                ms.Close();
                return ret.ToString();
            }
            #endregion
     
            #region 加密字符串 密钥为系统默认 0123456789
            /// <summary>
            /// 加密字符串 密钥为系统默认
            /// </summary>
            /// <param name="inputStr">输入字符串</param>
            /// <returns>输出加密后字符串</returns>
            static public string SEncryptString(string inputStr)
            {
                MySecurity ws = new MySecurity();
                return ws.EncryptString(inputStr, "");
            }
            #endregion
     
     
            #region 加密文件
            /// <summary>
            /// 加密文件
            /// </summary>
            /// <param name="filePath">输入文件路径</param>
            /// <param name="savePath">加密后输出文件路径</param>
            /// <param name="keyStr">密码,可以为“”</param>
            /// <returns></returns> 
            public bool EncryptFile(string filePath, string savePath, string keyStr)
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                if (keyStr == "")
                    keyStr = key;
                FileStream fs = File.OpenRead(filePath);
                byte[] inputByteArray = new byte[fs.Length];
                fs.Read(inputByteArray, 0, (int)fs.Length);
                fs.Close();
                byte[] keyByteArray = Encoding.Default.GetBytes(keyStr);
                SHA1 ha = new SHA1Managed();
                byte[] hb = ha.ComputeHash(keyByteArray);
                sKey = new byte[8];
                sIV = new byte[8];
                for (int i = 0; i < 8; i++)
                    sKey[i] = hb[i];
                for (int i = 8; i < 16; i++)
                    sIV[i - 8] = hb[i];
                des.Key = sKey;
                des.IV = sIV;
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                fs = File.OpenWrite(savePath);
                foreach (byte b in ms.ToArray())
                {
                    fs.WriteByte(b);
                }
                fs.Close();
                cs.Close();
                ms.Close();
                return true;
            }
            #endregion
     
            #region 解密字符串
            /// <summary>
            /// 解密字符串
            /// </summary>
            /// <param name="inputStr">要解密的字符串</param>
            /// <param name="keyStr">密钥</param>
            /// <returns>解密后的结果</returns>
            static public string SDecryptString(string inputStr, string keyStr)
            {
                MySecurity ws = new MySecurity();
                return ws.DecryptString(inputStr, keyStr);
            }
            /// <summary>
            ///  解密字符串 密钥为系统默认
            /// </summary>
            /// <param name="inputStr">要解密的字符串</param>
            /// <returns>解密后的结果</returns>
            static public string SDecryptString(string inputStr)
            {
                MySecurity ws = new MySecurity();
                return ws.DecryptString(inputStr, "");
            }
            /// <summary>
            /// 解密字符串
            /// </summary>
            /// <param name="inputStr">要解密的字符串</param>
            /// <param name="keyStr">密钥</param>
            /// <returns>解密后的结果</returns>
            public string DecryptString(string inputStr, string keyStr)
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                if (keyStr == "")
                    keyStr = key;
                byte[] inputByteArray = new byte[inputStr.Length / 2];
                for (int x = 0; x < inputStr.Length / 2; x++)
                {
                    int i = (Convert.ToInt32(inputStr.Substring(x * 2, 2), 16));
                    inputByteArray[x] = (byte)i;
                }
                byte[] keyByteArray = Encoding.Default.GetBytes(keyStr);
                SHA1 ha = new SHA1Managed();
                byte[] hb = ha.ComputeHash(keyByteArray);
                sKey = new byte[8];
                sIV = new byte[8];
                for (int i = 0; i < 8; i++)
                    sKey[i] = hb[i];
                for (int i = 8; i < 16; i++)
                    sIV[i - 8] = hb[i];
                des.Key = sKey;
                des.IV = sIV;
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                StringBuilder ret = new StringBuilder();
                return System.Text.Encoding.Default.GetString(ms.ToArray());
            }
            #endregion
     
            #region 解密文件
            /// <summary>
            /// 解密文件
            /// </summary>
            /// <param name="filePath">输入文件路径</param>
            /// <param name="savePath">解密后输出文件路径</param>
            /// <param name="keyStr">密码,可以为“”</param>
            /// <returns></returns>   
            public bool DecryptFile(string filePath, string savePath, string keyStr)
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                if (keyStr == "")
                    keyStr = key;
                FileStream fs = File.OpenRead(filePath);
                byte[] inputByteArray = new byte[fs.Length];
                fs.Read(inputByteArray, 0, (int)fs.Length);
                fs.Close();
                byte[] keyByteArray = Encoding.Default.GetBytes(keyStr);
                SHA1 ha = new SHA1Managed();
                byte[] hb = ha.ComputeHash(keyByteArray);
                sKey = new byte[8];
                sIV = new byte[8];
                for (int i = 0; i < 8; i++)
                    sKey[i] = hb[i];
                for (int i = 8; i < 16; i++)
                    sIV[i - 8] = hb[i];
                des.Key = sKey;
                des.IV = sIV;
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                fs = File.OpenWrite(savePath);
                foreach (byte b in ms.ToArray())
                {
                    fs.WriteByte(b);
                }
                fs.Close();
                cs.Close();
                ms.Close();
                return true;
            }
            #endregion
     
     
            #region MD5加密
            /// <summary>
            /// 128位MD5算法加密字符串
            /// </summary>
            /// <param name="text">要加密的字符串</param>   
            public static string MD5(string text)
            {
     
                //如果字符串为空,则返回
                if (Tools.IsNullOrEmpty<string>(text))
                {
                    return "";
                }
                //返回MD5值的字符串表示
                return MD5(text);
            }
     
            /// <summary>
            /// 128位MD5算法加密Byte数组
            /// </summary>
            /// <param name="data">要加密的Byte数组</param>   
            public static string MD5(byte[] data)
            {
                //如果Byte数组为空,则返回
                if (Tools.IsNullOrEmpty<byte[]>(data))
                {
                    return "";
                }
     
                try
                {
                    //创建MD5密码服务提供程序
                    MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
     
                    //计算传入的字节数组的哈希值
                    byte[] result = md5.ComputeHash(data);
     
                    //释放资源
                    md5.Clear();
     
                    //返回MD5值的字符串表示
                    return Convert.ToBase64String(result);
                }
                catch
                {
     
                    //LogHelper.WriteTraceLog(TraceLogLevel.Error, ex.Message);
                    return "";
                }
            }
            #endregion
     
            #region Base64加密
            /// <summary>
            /// Base64加密
            /// </summary>
            /// <param name="text">要加密的字符串</param>
            /// <returns></returns>
            public static string EncodeBase64(string text)
            {
                //如果字符串为空,则返回
                if (Tools.IsNullOrEmpty<string>(text))
                {
                    return "";
                }
     
                try
                {
                    char[] Base64Code = new char[]{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T',
                                                'U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n',
                                                'o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7',
                                                '8','9','+','/','='};
                    byte empty = (byte)0;
                    ArrayList byteMessage = new ArrayList(Encoding.Default.GetBytes(text));
                    StringBuilder outmessage;
                    int messageLen = byteMessage.Count;
                    int page = messageLen / 3;
                    int use = 0;
                    if ((use = messageLen % 3) > 0)
                    {
                        for (int i = 0; i < 3 - use; i++)
                            byteMessage.Add(empty);
                        page++;
                    }
                    outmessage = new System.Text.StringBuilder(page * 4);
                    for (int i = 0; i < page; i++)
                    {
                        byte[] instr = new byte[3];
                        instr[0] = (byte)byteMessage[i * 3];
                        instr[1] = (byte)byteMessage[i * 3 + 1];
                        instr[2] = (byte)byteMessage[i * 3 + 2];
                        int[] outstr = new int[4];
                        outstr[0] = instr[0] >> 2;
                        outstr[1] = ((instr[0] & 0x03) << 4) ^ (instr[1] >> 4);
                        if (!instr[1].Equals(empty))
                            outstr[2] = ((instr[1] & 0x0f) << 2) ^ (instr[2] >> 6);
                        else
                            outstr[2] = 64;
                        if (!instr[2].Equals(empty))
                            outstr[3] = (instr[2] & 0x3f);
                        else
                            outstr[3] = 64;
                        outmessage.Append(Base64Code[outstr[0]]);
                        outmessage.Append(Base64Code[outstr[1]]);
                        outmessage.Append(Base64Code[outstr[2]]);
                        outmessage.Append(Base64Code[outstr[3]]);
                    }
                    return outmessage.ToString();
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            #endregion
     
            #region Base64解密
            /// <summary>
            /// Base64解密
            /// </summary>
            /// <param name="text">要解密的字符串</param>
            public static string DecodeBase64(string text)
            {
                //如果字符串为空,则返回
                if (Tools.IsNullOrEmpty<string>(text))
                {
                    return "";
                }
     
                //将空格替换为加号
                text = text.Replace(" ", "+");
     
                try
                {
                    if ((text.Length % 4) != 0)
                    {
                        return "包含不正确的BASE64编码";
                    }
                    if (!Regex.IsMatch(text, "^[A-Z0-9/+=]*$", RegexOptions.IgnoreCase))
                    {
                        return "包含不正确的BASE64编码";
                    }
                    string Base64Code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
                    int page = text.Length / 4;
                    ArrayList outMessage = new ArrayList(page * 3);
                    char[] message = text.ToCharArray();
                    for (int i = 0; i < page; i++)
                    {
                        byte[] instr = new byte[4];
                        instr[0] = (byte)Base64Code.IndexOf(message[i * 4]);
                        instr[1] = (byte)Base64Code.IndexOf(message[i * 4 + 1]);
                        instr[2] = (byte)Base64Code.IndexOf(message[i * 4 + 2]);
                        instr[3] = (byte)Base64Code.IndexOf(message[i * 4 + 3]);
                        byte[] outstr = new byte[3];
                        outstr[0] = (byte)((instr[0] << 2) ^ ((instr[1] & 0x30) >> 4));
                        if (instr[2] != 64)
                        {
                            outstr[1] = (byte)((instr[1] << 4) ^ ((instr[2] & 0x3c) >> 2));
                        }
                        else
                        {
                            outstr[2] = 0;
                        }
                        if (instr[3] != 64)
                        {
                            outstr[2] = (byte)((instr[2] << 6) ^ instr[3]);
                        }
                        else
                        {
                            outstr[2] = 0;
                        }
                        outMessage.Add(outstr[0]);
                        if (outstr[1] != 0)
                            outMessage.Add(outstr[1]);
                        if (outstr[2] != 0)
                            outMessage.Add(outstr[2]);
                    }
                    byte[] outbyte = (byte[])outMessage.ToArray(Type.GetType("System.Byte"));
                    return Encoding.Default.GetString(outbyte);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            #endregion
        }
    }
  • 相关阅读:
    mysql常见的优化方法
    Mac 怎么通过自带终端连接linux服务器
    基于 appium 的 UI 自动化测试
    sourcetree在mac上的使用
    mac下git安装和使用
    mac 上更改环境变量
    Mac环境下svn的使用
    jira常用配置
    influxDB基本操作
    Collectd 和 InfluxDB 的部署和使用
  • 原文地址:https://www.cnblogs.com/xdot/p/5169097.html
Copyright © 2011-2022 走看看