1. 程式人生 > >程式設計師之網路安全系列(三):資料加密之對稱加密演算法

程式設計師之網路安全系列(三):資料加密之對稱加密演算法

系列目錄:

前文回顧

假如,明明和麗麗相互不認識,明明想給麗麗寫一封情書,讓隔壁老王送去

  1. 如何保證隔壁老王不能看到情書內容?(保密性)
  2. 如何保證隔壁老王不修改情書的內容?(完整性)
  3. 如何保證隔壁老王不冒充明明?(身份認證)
  4. 如何保證明明不能否認情書是自己寫的?(來源的不可否認)

上一節,我們使用了Hash演算法保證了情書的完整性,也就是確保“隔壁王叔叔”沒有修改明明的情書,那麼這一節我們來看看如何保證“隔壁王叔叔”不能看到情書的內容,也就是保密性。

資料加密

要想不讓別人看到資料,那麼我們就們就需要對資料加密。

加密技術 是最常用的安全保密手段,利用技術手段把重要的資料變為亂碼(加密)傳送,到達目的地後再用相同或不同的手段還原(解密)。
加密包括兩個元素:演算法和金鑰。一個加密演算法是將普通的文字(或者可以理解的資訊)與一竄數字(金鑰)的結合,產生不可理解的密文的步驟,金鑰是用來對資料進行編碼和解碼的一種演算法。

舉個例子:

假設我們要對LOVE加密,我們可以先定義字母的順序ABCDEFGHIJKLMNOPQRSTUVWXYZ,然後我們讓每個字母向後移動兩位,那麼LOVE就變為了NQXG

L------>N
O------>Q
V------>X
E------>
LOVE--->NQXG

我想這就是最簡單的加密方式。

金鑰加密技術的密碼體制分為對稱金鑰體制和非對稱金鑰體制兩種。

對資料加密的技術分為兩類,即對稱加密(私人金鑰加密)和非對稱加密(公開金鑰加密)。對稱加密以資料加密標準(DES,Data Encryption Standard)演算法為典型代表,非對稱加密通常以RSA(Rivest Shamir Ad1eman)演算法為代表。對稱加密的加密金鑰和解密金鑰相同,而非對稱加密的加密金鑰和解密金鑰不同,加密金鑰可以公開而解密金鑰需要保密。

對稱加密

對稱加密採用了對稱密碼編碼技術,它的特點是檔案加密和解密使用相同的金鑰,即加密金鑰也可以用作解密金鑰。
比如,我們給WORD文件設定密碼1234, 那麼其他人想要開啟文件也必須輸入1234才能開啟。

常用加密演算法:

  • DES(Data Encryption Standard):資料加密標準,速度較快,適用於加密大量資料的場合。
  • 3DES(Triple DES):是基於DES,對一塊資料用三個不同的金鑰進行三次加密,強度更高。
  • AES(Advanced Encryption Standard):高階加密標準,是下一代的加密演算法標準,速度快,安全級別高;
  • RC4,也是為 RSA Data Security, Inc. 開發的密碼系統的商標名稱。

傳統的DES由於只有56位的金鑰,從1997年開始,RSA公司發起了一個稱作“向DES挑戰”的競技賽。在首屆挑戰賽上,羅克·維瑟用了96天時間破解了用DES加密的一段資訊。1999年12月22日,RSA公司發起“第三屆DES挑戰賽(DES Challenge III)”。2000年1月19日,由電子邊疆基金會組織研製的25萬美元的DES解密機以22.5小時的戰績,成功地破解了 DES加密演算法。DES已逐漸完成了它的歷史使命。

高階加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。經過五年的甄選流程,高階加密標準由美國國家標準與技術研究院(NIST)於2001年11月26日釋出於FIPS PUB 197,並在2002年5月26日成為有效的標準。2006年,高階加密標準已然成為對稱金鑰加密中最流行的演算法之一。

對稱加密演算法的優點:

  • 演算法公開
  • 計算量小
  • 加密速度快,加密效率高

對稱加密演算法的缺點

  • 加解密雙方需要使用相同的祕鑰
  • 祕鑰管理很不方便,如果使用者很多,那麼祕鑰的管理成幾何性增長
  • 任何一方祕鑰洩露,資料都不安全了

最後

通過本節,我們知道當明明給麗麗情書時,可以用DES或者AES對資料進行加密,即使“隔壁王叔叔”拿到信件也看不懂內容,同時使用上一節的Hash演算法保證了情書的內容完整,但是這就需要明明和麗麗提前設定一個祕鑰。

程式碼示例

下面的程式碼輸出如下結果

    I Love You, Li Li
    Encrypeted: 0t9glwGMmwtGs8B4QCotyZkKf091WElCwG659QiVVw0=
    Decrypeted: I Love You, Li Li
    

.NET 原始碼:

    using System;
    using System.Security.Cryptography;
    using System.IO;
    using System.Text;

    namespace AES
    {
        class MainClass
        {
            public static void Main (string[] args)
            {
                string password = "Don't believe wang shu shu";
                string orginTextToSent = "I Love You, Li Li";
                Console.WriteLine (orginTextToSent);

                string encryptedText=EncryptText(orginTextToSent, password);

                Console.WriteLine ("Encrypeted: " + encryptedText);

                string DecryptedText = DecryptText (encryptedText, password);
                Console.WriteLine ("Decrypeted: " + DecryptedText);

            }



            public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
            {
                byte[] encryptedBytes = null;

                // Set your salt here, change it to meet your flavor:
                // The salt bytes must be at least 8 bytes.
                byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

                using (MemoryStream ms = new MemoryStream())
                {
                    using (RijndaelManaged AES = new RijndaelManaged())
                    {
                        AES.KeySize = 256;
                        AES.BlockSize = 128;

                        var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                        AES.Key = key.GetBytes(AES.KeySize / 8);
                        AES.IV = key.GetBytes(AES.BlockSize / 8);

                        AES.Mode = CipherMode.CBC;

                        using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
                        {
                            cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                            cs.Close();
                        }
                        encryptedBytes = ms.ToArray();
                    }
                }

                return encryptedBytes;
            }

            public static byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
            {
                byte[] decryptedBytes = null;

                // Set your salt here, change it to meet your flavor:
                // The salt bytes must be at least 8 bytes.
                byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

                using (MemoryStream ms = new MemoryStream())
                {
                    using (RijndaelManaged AES = new RijndaelManaged())
                    {
                        AES.KeySize = 256;
                        AES.BlockSize = 128;

                        var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                        AES.Key = key.GetBytes(AES.KeySize / 8);
                        AES.IV = key.GetBytes(AES.BlockSize / 8);

                        AES.Mode = CipherMode.CBC;

                        using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
                        {
                            cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                            cs.Close();
                        }
                        decryptedBytes = ms.ToArray();
                    }
                }

                return decryptedBytes;
            }


            public static string EncryptText(string input, string password)
            {
                // Get the bytes of the string
                byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);

                // Hash the password with SHA256
                passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

                byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);

                string result = Convert.ToBase64String(bytesEncrypted);

                return result;
            }

            public static string DecryptText(string input, string password)
            {
                // Get the bytes of the string
                byte[] bytesToBeDecrypted = Convert.FromBase64String(input);
                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
                passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

                byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes);

                string result = Encoding.UTF8.GetString(bytesDecrypted);

                return result;
            }

        }
    }

相關推薦

程式設計師網路安全系列資料加密對稱加密演算法

系列目錄: 前文回顧 假如,明明和麗麗相互不認識,明明想給麗麗寫一封情書,讓隔壁老王送去 如何保證隔壁老王不能看到情書內容?(保密性) 如何保證隔壁老王不修改情書的內容?(完整性) 如何保證隔壁老王不冒充明明?(身份認證) 如何保證明明不能否認情書是自己寫的?(來源的不可否認) 上一節,我們使用了Ha

程式設計師網路安全系列資料加密對稱祕鑰

系列目錄: 前文回顧 假如,明明和麗麗相互不認識,明明想給麗麗寫一封情書,讓隔壁老王送去 如何保證隔壁老王不能看到情書內容?(保密性) 如何保證隔壁老王不修改情書的內容?(完整性) 如何保證隔壁老王不冒充明明?(身份認證) 如何保證明明不能否認情書是自己寫的?(來源的不可否認) 但是上面的問題是明

程式設計師網路安全系列為什麼要關注網路安全

系列目錄: 假如,明明和麗麗相互不認識,明明想給麗麗寫一封情書,讓隔壁老王送去 如何保證隔壁老王不能看到情書內容?(保密性) 如何保證隔壁老王不修改情書的內容?(完整性) 如何保證隔壁老王不冒充明明?(身份認證) 如何保證明明不能否認情書是自己寫的?(來源的不可否認) 前言 大家都知道最近幾年鬧的沸

程式設計師網路安全系列動態密碼

系列目錄 前文回顧 程式設計師之網路安全系列(五):數字證書以及12306的證書問題 我們使用了數字證書,確保了對方的公鑰身份,也就是網際網路中確定了要訪問的網站就是你要訪問的網站。 但是我們如何確定要訪問這個網站的使用者就是要訪問的使用者呢? 對銀行來說需要確保“敏捷的水”登入銀行時,必須是"敏捷

程式設計師網路安全系列數字證書以及12306的證書問題

系列目錄: 前文回顧 假如,明明和麗麗相互不認識,明明想給麗麗寫一封情書,讓隔壁老王送去 如何保證隔壁老王不能看到情書內容?(保密性) 如何保證隔壁老王不修改情書的內容?(完整性) 如何保證隔壁老王不冒充明明?(身份認證) 如何保證明明不能否認情書是自己寫的?(來源的不可否認) 中間人攻擊 上面

程式設計師網路安全系列如何安全儲存使用者密碼及雜湊演算法

系列目錄: 前言 在很多網站的早期,甚至是現在仍然有一些網站,當你點選忘記密碼功能時,你的郵箱會收到一封郵件,然後裡面赫然寫著你的密碼,很多普通使用者還會覺得慶幸,總算是找回來了,殊不知,這是多麼可怕地一件事,說明了網站是“幾乎是”明文儲存你的密碼,一旦資料使用者資料洩露或者被拖庫,那麼使用者密碼將赤裸裸

Web安全系列XSS 攻擊進階挖掘漏洞

前言 目前來說,XSS 的漏洞型別主要分為三類:反射型、儲存型、DOM型,在本篇文章當中會以permeate生態測試系統為例,分析網站功能,引導攻擊思路,幫助讀者能夠快速找出網站可能存在的漏洞。 反射型 XSS 挖掘 現在筆者需要進行手工XSS漏洞挖掘,在手工挖掘之前筆者需要先逛逛網站有哪些功能點,如下圖是

CentOS 7Postfix部署系列postfix和Dovecot配置

-o art 4.2 water 修改 ins har fir mail -----提供AD\Exchange\Lync\Sharepoint\CRM\SC\O365等微軟產品實施及外包,QQ:185426445.電話18666943750https://tecadmin.

java程式設計師菜鳥進階 HTTP權威指南 HTTP連線管理及對TCP效能的考慮

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

深入淺出Mybatis原始碼系列---配置詳解properties與environmentsmybatis原始碼篇

上篇文章《深入淺出Mybatis原始碼系列(二)---配置簡介(mybatis原始碼篇)》我們通過對mybatis原始碼的簡單分析,可看出,在mybatis配置檔案中,在configuration根節點下面,可配置properties、typeAliases、plugins、

複習shiro安全框架——通過jdbcRealm連線資料庫

shiro提供jdbcRealm連線資料庫 這裡要連線資料庫所有要依賴一些jar包 <dependency> <groupId>org.apache.shiro</groupId>

android 電容屏驅動除錯驅動程式分析篇

關鍵詞:android  電容屏 tp 工作佇列 中斷 坐點計算  電容屏主要引數 平臺資訊: 核心:linux2.6/linux3.0 系統:android/android4.0  平臺:S5PV310(samsung exynos 4210)  作者:xubin3417

用Python寫網路爬蟲系列表單處理

import urllib,urllib2 LOGIN_URL = r'http://example.webscraping.com/user/login' LOGIN_EMAIL = '[email protected]' LOGIN_PASSWORD ='q

Java程式設計師面試題及解答

二、Web篇 這部分主要是與Java Web和Web Service相關的面試題。 96、闡述Servlet和CGI的區別?  答:Servlet與CGI的區別在於Servlet處於伺服器程序中,它通過多執行緒方式執行其service()方法,一個例項可

深度學習系列簡單網路的自編碼學習

本節將研究深度學習網路權值設計的重要思想之一:自編碼思想,在正式介紹之前先以一個簡單的介紹一篇,一層隱含層網路的自編碼學習問題。 什麼是自編碼?所謂自編碼就是自己給自己編碼,再簡單點就是令輸出等於輸入自己。以一個簡單三層網路為例如下: 這裡我們假設輸出等

程式設計師必會技能系列2git中merge和rebase比較-3

git中有兩個合併分支的方法,一個是git merge,另一個是git rebase。 一、git merge 講解 1、畫圖講解git merge 用merge合併分支時不會改變歷史(通俗的說就是commit號不會變)。在git中merge會創造一個

深入淺出Mybatis系列---配置詳解properties與environmentsmybatis原始碼篇

上篇文章《深入淺出Mybatis系列(二)---配置簡介(mybatis原始碼篇)》我們通過對mybatis原始碼的簡單分析,可看

“造輪運動” ORM框架系列~ 乾貨呈上

   這一趴裡面,我就來正式介紹一下CoffeeSQL的乾貨。     首先要給CoffeeSQL來個定位:最開始就是由於本人想要了解ORM框架內部的原理,所以就四處搜尋有關的部落格與學習資料,就是在那個夏天,在部落格園上看到了一位7tiny老哥的部落格(https://www.

前端程式設計師學好算法系列陣列

前端程式設計師怎麼才能學好演算法呢?目前演算法優秀的視訊集中在c++,java,python,本人通過幾個月專心看c++的視訊掌握了演算法的基本思路,都翻譯成前端程式碼一一寫出來,從真題到思維全面提升演算法思維面對演算法面試,不畏懼 二分查詢法O(logn)尋找陣列中的最大/最小值O(N)歸併排序演算法 O(

Spring Cloud系列Eureka原始碼解析服務端

一、自動裝配   1、根據自動裝配原理(詳見:Spring Boot系列(二):Spring Boot自動裝配原理解析),找到spring-cloud-starter-netflix-eureka-server.jar的spring.factories,檢視spring.factories如下:   2、進