国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
.NET中非對(duì)稱加密RSA算法的密鑰保存

前面介紹了如何在.NET中使用RSA算法進(jìn)行數(shù)據(jù)加密和簽名,很多時(shí)候,我們需要重復(fù)的使用一組密鑰,因此就需要將這組密鑰保存起來(lái)。接下來(lái),我給大家介紹3種在.Net中保存密鑰的方法。

  • 第一種方法:將密鑰導(dǎo)出保存為本地文件。

首先要強(qiáng)調(diào)的是,出于安全性考慮,不建議使用這種方法保存私鑰,如果使用,請(qǐng)?jiān)诿荑€導(dǎo)出的時(shí)候只導(dǎo)出公鑰。

RSACryptoServiceProvider對(duì)象提供了一個(gè)ToXmlString(bool includePrivateParameters)方法,我們可以使用此方法將密鑰導(dǎo)出為一個(gè)xml格式的string,然后將其保存到一個(gè)文件中,這個(gè)方法的參數(shù)為true時(shí)會(huì)導(dǎo)出私鑰,否則不導(dǎo)出私鑰。需要的時(shí)候,我們可以使用FromXmlString(string xmlString)方法,將保存的密鑰信息加載到RSACryptoServiceProvider對(duì)象中。下面的代碼實(shí)現(xiàn)了導(dǎo)出和導(dǎo)入操作:
 
static void SaveKey2File(RSACryptoServiceProvider rsa, string fileName)
        { 
            FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
            string key = rsa.ToXmlString(false); 
            fs.Write(Encoding.UTF8.GetBytes(key), 0, key.Length);
            fs.Close(); 
            fs.Dispose(); 
        } 
        static void LoadKeyFromFile(RSACryptoServiceProvider rsa, string fileName) 
        { 
            FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
            byte[] data = new byte[fs.Length];
            fs.Read(data, 0, (int)fs.Length); 
            fs.Close();
            fs.Dispose();
            rsa.FromXmlString(Encoding.UTF8.GetString(data));
        }
 

實(shí)際的工作中,出于安全性考慮,很少會(huì)用的上面的方法保存密鑰,但如果你想看看密鑰長(zhǎng)什么樣子,這個(gè)方法還是挺有用的~~

  • 第二種方法:將密鑰保存到密鑰容器。

什么是密鑰容器(key container)呢?Window系統(tǒng)提供兩種密鑰庫(kù)(key store)用來(lái)保存密鑰(User Key Store和Machine Key Store),而密鑰容器就是用來(lái)保存密鑰的一個(gè)單位,每個(gè)密鑰容器都包含了一組密鑰對(duì)(公鑰和私鑰)和一些其它的信息,例如是否允許導(dǎo)出密鑰,密鑰的種類(Exchange或Signatrue)等等,我們可以通過(guò)密鑰容器的名稱來(lái)訪問(wèn)它們。

使用CspParameters對(duì)象創(chuàng)建或使用密鑰容器:

         //實(shí)例化CspParameters對(duì)象 
        CspParameters cspPara = new CspParameters(); 
        //指定CspParameters對(duì)象實(shí)例的名稱  
        cspPara.KeyContainerName = "key_container_test"; 
        //設(shè)置密鑰類型為Exchange  
        cspPara.KeyNumber = 1;  
        //設(shè)置密鑰容器保存到計(jì)算機(jī)密鑰庫(kù)(默認(rèn)為用戶密鑰庫(kù)) 
        cspPara.Flags = CspProviderFlags.UseMachineKeyStore; 
        //實(shí)例化RSA對(duì)象的時(shí)候,將CspParameters對(duì)象作為構(gòu)造函數(shù)的參數(shù)傳遞給RSA對(duì)象,
        //如果名稱為key_container_test的密鑰容器不存在,RSA對(duì)象會(huì)創(chuàng)建這個(gè)密鑰容器;
        //如果名稱為key_container_test的密鑰容器已經(jīng)存在,RSA對(duì)象會(huì)使用這個(gè)密鑰容
        //器中的密鑰進(jìn)行實(shí)例化
        RSACryptoServiceProvider rsaPro = new RSACryptoServiceProvider(cspPara);
 

刪除密鑰容器:當(dāng)我們不再需要某個(gè)密鑰容器的時(shí)候,可以使用下面的方法進(jìn)行刪除。

        CspParameters cspPara = new CspParameters();
        cspPara.KeyContainerName = "key_container_test"; 
        cspPara.Flags = CspProviderFlags.UseMachineKeyStore;  
        RSACryptoServiceProvider rsaPro = new RSACryptoServiceProvider(cspPara); 
        //不在密鑰庫(kù)中保存此密鑰容器
        rsaPro.PersistKeyInCsp = false; 
        //釋放rsaPro占用的所有資源,包括密鑰容器。 
        rsaPro.Clear();

除非知道密鑰容器的名稱,否則無(wú)法從密鑰庫(kù)中提取到這個(gè)密鑰容器,所以在本機(jī)使用的密鑰(尤其是私鑰)保存在密鑰容器中是比較安全的做法。

注:實(shí)際當(dāng)我們實(shí)例化一個(gè)RSACryptoServiceProvider 對(duì)象的時(shí)候,如果不指定具體的CspParameters 對(duì)象,RSACryptoServiceProvider 對(duì)象會(huì)生成一個(gè)臨時(shí)的密鑰容器,并且在RSACryptoServiceProvider 對(duì)象銷毀的時(shí)候自動(dòng)刪除這個(gè)臨時(shí)的密鑰容器。

  • 第三種方法:使用數(shù)字證書。

如果你的密鑰需要在不同的機(jī)器上使用,那么將密鑰保存在數(shù)字證書中是一個(gè)不錯(cuò)的選擇。實(shí)際上,說(shuō)將密鑰保存在數(shù)字證書中并不準(zhǔn)確,應(yīng)該是先生成一個(gè)數(shù)字證書,然后在使用數(shù)字證書中的密鑰。

如何生成一個(gè)數(shù)字證書呢?正式的數(shù)字證書需要到CA去申請(qǐng),當(dāng)然還要奉上一筆銀子。還好我們可以使用.Net SDK提供的MakeCert.exe來(lái)生成臨時(shí)的數(shù)字證書。具體如何生成請(qǐng)?jiān)L問(wèn)證書創(chuàng)建工具。

.Net中用來(lái)訪問(wèn)證書的對(duì)象是X509Certificate2,我們可以用它來(lái)加載一個(gè)數(shù)字證書并獲得數(shù)字證書中的密鑰。

如果證書是以文件的形式保存在本地的話,可以用下面的方法加載:
 
         static byte[] EncryptDataByCert(byte[] data) 
         {  
             //實(shí)例化一個(gè)X509Certificate2對(duì)象,并加載證書testCertificate.cer 
             X509Certificate2 cert = new X509Certificate2(@"c:\testCertificate.cer"); 
             //將證書的公鑰強(qiáng)制轉(zhuǎn)換成一個(gè)RSACryptoServiceProvider對(duì)象,然后可以使用這個(gè)對(duì)象執(zhí)行加密操作 
             RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PublicKey.Key;
             byte[] enData = rsa.Encrypt(data, false); 
             return enData; 
         }
 
一般情況下,對(duì)于數(shù)字證書來(lái)說(shuō),保存公鑰的證書使用.cer做擴(kuò)展名,而保存了私鑰的證書會(huì)使用.pfx做擴(kuò)展名,當(dāng)我們加載一個(gè)私鑰的數(shù)字證書時(shí),需要提供私鑰的保護(hù)密碼,代碼如下:
          static string DecryptByCert(byte[] endata) 
         {  
             //實(shí)例化一個(gè)X509Certificate2對(duì)象,并加載證書testCertificate.pfx。 
             //由于證書testCertificate.pfx包含私鑰,所以需要提供私鑰的保護(hù)密碼(第二個(gè)參數(shù)) 
             X509Certificate2 cert = new X509Certificate2(@"c:\testCertificate.pfx", "123456"); 
             //將證書testCertificate.pfx的私鑰強(qiáng)制轉(zhuǎn)換為一個(gè)RSACryptoServiceProvider對(duì)象,用于解密操作 
             RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey;
             byte[] data = rsa.Decrypt(endata, false); 
             return data; 
         }
 
如果證書保存在計(jì)算機(jī)的證書存儲(chǔ)區(qū)(Certificate Store)中,我們就需要使用另一個(gè)對(duì)象X509Store來(lái)訪問(wèn)證書存儲(chǔ)區(qū)。根據(jù)訪問(wèn)權(quán)限,證書存儲(chǔ)區(qū)分為當(dāng)前用戶(Current User)和本地計(jì)算機(jī)(Local Machine)兩個(gè)部分,前者用來(lái)保存當(dāng)前登錄的用戶所能使用的數(shù)字證書,而后者用來(lái)保存登錄到本機(jī)所能使用的數(shù)字證書。不管是當(dāng)前用戶還是本地計(jì)算機(jī),都包含多個(gè)邏輯存儲(chǔ)區(qū),它們通過(guò)不同的名稱來(lái)區(qū)分,每個(gè)邏輯存儲(chǔ)區(qū)可以保存多個(gè)數(shù)字證書。更詳細(xì)的介紹,可以參考證書。具體的訪問(wèn)證書存儲(chǔ)區(qū)的代碼如下:
 
         private X509Certificate2 GetCertificate(string CertName) 
        { 
            //聲明X509Store對(duì)象,指定存儲(chǔ)區(qū)的名稱和存儲(chǔ)區(qū)的類型  
            //StoreName中定義了系統(tǒng)默認(rèn)的一些存儲(chǔ)區(qū)的邏輯名稱  
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);  
            //以只讀的方式打開這個(gè)存儲(chǔ)區(qū),OpenFlags定義的打開的方式  
            store.Open(OpenFlags.ReadOnly); 
            //獲取這個(gè)存儲(chǔ)區(qū)中的數(shù)字證書的集合 
            X509Certificate2Collection certCol = store.Certificates; 
            //查找滿足證書名稱的證書并返回 
            foreach (X509Certificate2 cert in certCol)
            {
                if (cert.SubjectName.Name == "CN="  + CertName)
                { 
                    store.Close();
                    return cert; 
                } 
            } 
            store.Close();
            return null;
        }
 

我們也可以通過(guò)X509Certificate2Collection 對(duì)象在當(dāng)前存儲(chǔ)區(qū)中添加刪除證書,詳細(xì)的信息可以參考證書存儲(chǔ)區(qū)。

上面的介紹是我自己對(duì)密鑰保存的一些理解,大家可以根據(jù)的具體情況,去選擇具體的方法,希望對(duì)大家有所幫助。如果哪位大神有更好的方法,希望留下你的方法共我們學(xué)習(xí)。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
使用X.509數(shù)字證書加密解密實(shí)務(wù)(三)-- 使用RSA證書結(jié)合對(duì)稱加密技術(shù)加密長(zhǎng)數(shù)據(jù)
創(chuàng)建X509證書,并獲取證書密鑰的一點(diǎn)研究
最通俗易懂的RSA加密解密指導(dǎo)
net加密基礎(chǔ)2
C#開發(fā)中常用加密解密方法解析
演練:創(chuàng)建加密應(yīng)用程序
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服