zoukankan      html  css  js  c++  java
  • [C#.NET] 使用 X509 數位電子簽章 加解密

    摘自: http://www.dotblogs.com.tw/yc421206/archive/2012/06/30/73150.aspx

    上篇提到了使用X509的的憑證使用方式,請參考 [C#.NET] X509 數位電子簽章

    這次便來進入主題加解密,要使用憑證來加解密,憑證必須要帶有私密金鑰,否則會無法解密,

    PS.對於資安這塊實在完全不瞭解,憑證信任等等相關設定,我也不懂,問 方丈 也只是得到了些天書答案,完全不知道它講的天書是哪個章節,我只會拿憑證來加解密而已,若有憑證問題請找咱們家的 方丈

     

    X509 是用RSA演算法來處理加解密的,所以邏輯完全跟之前的帖子一樣,請參考:

    [C#.NET] 字串及檔案,利用 RSA 演算法加解密

    [C#.NET] RSA的長度限制

     

    重點是這句:var rsaCrypto = (RSACryptoServiceProvider)this.Certificate.PublicKey.Key;

    還記得RSA的限制吧?所以一樣採用分段加密,加密邏輯如下:

     

     

    public byte[] Encryptor(byte[] OriginalData)
    {
        if (OriginalData == null) throw new ArgumentNullException("OriginalData");
        if (OriginalData.Length <= 0) throw new ArgumentOutOfRangeException("OriginalData");
        if (this.Certificate == null)
        {
            //使用預設憑證
            var defaultCert = RsaAndX509.Properties.Resources.artag_certnew;
            this.Certificate = new X509Certificate2(defaultCert, "pass@w0rd1");
        }
        var rsaCrypto = (RSACryptoServiceProvider)this.Certificate.PublicKey.Key;
    
        int bufferSize = (rsaCrypto.KeySize / 8) - 11;
        byte[] buffer = new byte[bufferSize];
        //分段加密
        using (MemoryStream input = new MemoryStream(OriginalData))
        using (MemoryStream ouput = new MemoryStream())
        {
            while (true)
            {
                int readLine = input.Read(buffer, 0, bufferSize);
                if (readLine <= 0)
                {
                    break;
                }
                byte[] temp = new byte[readLine];
                Array.Copy(buffer, 0, temp, 0, readLine);
                byte[] encrypt = rsaCrypto.Encrypt(temp, false);
                ouput.Write(encrypt, 0, encrypt.Length);
            }
            return ouput.ToArray();
        }
    }

     

    解密,重點是這句:var rsaCrypto = (RSACryptoServiceProvider)this.Certificate.PrivateKey;

    public byte[] Decryptor(byte[] EncryptDada)
    {
        if (EncryptDada == null) throw new ArgumentNullException("EncryptDada");
        if (EncryptDada.Length <= 0) throw new ArgumentOutOfRangeException("EncryptDada");
    
        if (this.Certificate == null)
        {
            //使用預設憑證
            var defaultCert = RsaAndX509.Properties.Resources.artag_certnew;
            this.Certificate = new X509Certificate2(defaultCert, "pass@w0rd1");
        }
    
        var rsaCrypto = (RSACryptoServiceProvider)this.Certificate.PrivateKey;
    
        int keySize = rsaCrypto.KeySize / 8;
        byte[] buffer = new byte[keySize];
    
        using (MemoryStream input = new MemoryStream(EncryptDada))
        using (MemoryStream output = new MemoryStream())
        {
            while (true)
            {
                int readLine = input.Read(buffer, 0, keySize);
                if (readLine <= 0)
                {
                    break;
                }
                byte[] temp = new byte[readLine];
                Array.Copy(buffer, 0, temp, 0, readLine);
                byte[] decrypt = rsaCrypto.Decrypt(temp, false);
                output.Write(decrypt, 0, decrypt.Length);
            }
            return output.ToArray();
        }
    }
     完整
    完整範例如下:
    namespace RsaAndX509
    {
        public class RsaCryptService
        {
            private Encoding _encoding = Encoding.UTF8;
     
            public Encoding Encoding
            {
                get { return _encoding; }
                set { _encoding = value; }
            }
     
            private X509ContentType _x509ContentType = X509ContentType.Cert;
     
            public X509ContentType X509ContentType
            {
                get { return _x509ContentType; }
                set { _x509ContentType = value; }
            }
     
            private StoreName _storeName = StoreName.My;
     
            public StoreName StoreName
            {
                get { return _storeName; }
                set { _storeName = value; }
            }
     
            private StoreLocation _locationr = StoreLocation.CurrentUser;
     
            public StoreLocation Location
            {
                get { return _locationr; }
                set { _locationr = value; }
            }
     
            private X509Certificate2 _certificate;
     
            public X509Certificate2 Certificate
            {
                get { return _certificate; }
                private set { _certificate = value; }
            }
     
            public X509Certificate2 CreateCertificate(string CertFile, string Password)
            {
                if (CertFile == null) throw new ArgumentNullException("CertFile");
                if (Password == null) throw new ArgumentNullException("Password");
                if (string.IsNullOrEmpty(Password))
                {
                    this.Certificate = new X509Certificate2(CertFile);
                }
                else
                {
                    this.Certificate = new X509Certificate2(CertFile, Password);
                }
     
                return this.Certificate;
            }
     
            public X509Certificate2 ImportCertificate(string CertFile, string Password)
            {
                if (CertFile == null) throw new ArgumentNullException("CertFile");
                if (Password == null) throw new ArgumentNullException("Password");
                var cert = this.CreateCertificate(CertFile, Password);
                if (cert == null) return null;
     
                X509Store store = new X509Store(this.StoreName, this.Location);
                store.Open(OpenFlags.ReadWrite);
                store.Add(cert);
                store.Close();
                return cert;
            }
     
            public bool ExportCertificate(string CertSubjectName, string ExportFile)
            {
                if (CertSubjectName == null) throw new ArgumentNullException("CertSubjectName");
                if (ExportFile == null) throw new ArgumentNullException("ExportFile");
                return ExportCertificate(CertSubjectName, null, ExportFile);
            }
     
            public bool ExportCertificate(string CertSubjectName, string Password, string ExportFile)
            {
                if (CertSubjectName == null) throw new ArgumentNullException("CertSubjectName");
                if (ExportFile == null) throw new ArgumentNullException("ExportFile");
                X509Store store = new X509Store(this.StoreName, this.Location);
                store.Open(OpenFlags.ReadOnly);
                FileStream fileStream = null;
                try
                {
                    fileStream = new FileStream(ExportFile, FileMode.Create, FileAccess.Write);
                    foreach (X509Certificate2 cert in store.Certificates)
                    {
                        if (cert.Subject == CertSubjectName)
                        {
                            byte[] CertByte;
     
                            if (string.IsNullOrEmpty(Password))
                            {
                                CertByte = cert.Export(X509ContentType);
                            }
                            else
                            {
                                CertByte = cert.Export(X509ContentType, Password);
                            }
                            fileStream.Write(CertByte, 0, CertByte.Length);
                            return true;
                        }
                    }
                }
                finally
                {
                    if (fileStream != null) fileStream.Dispose();
                    store.Close();
                }
                return false;
            }
     
            public void VerifyCertificate(X509Certificate2 Cert)
            {
                if (Cert == null) throw new ArgumentNullException("Ccert");
                X509Chain chain = new X509Chain();
     
                chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
                //RevocationStatusUnknown
                chain.Build(Cert);
     
                if (chain.ChainStatus.Length > 0)
                {
                    StringBuilder builder = new StringBuilder();
                    builder.AppendLine("憑證檢查錯誤:/r/n");
                    foreach (X509ChainStatus status in chain.ChainStatus)
                    {
                        builder.Append(string.Format("{0}={1}/r/n", status.Status, status.StatusInformation));
                    }
     
                    throw new ApplicationException(builder.ToString());
                }
                if (Cert.NotAfter <= DateTime.Now)
                {
                    throw new ApplicationException(string.Format("憑証過期"));
                }
            }
     
            public byte[] Encryptor(byte[] OriginalData)
            {
                if (OriginalData == null) throw new ArgumentNullException("OriginalData");
                if (OriginalData.Length <= 0) throw new ArgumentOutOfRangeException("OriginalData");
                if (this.Certificate == null)
                {
                    //使用資源檔裡的預設憑證
                    var defaultCert = RsaAndX509.Properties.Resources.artag_certnew;
                    this.Certificate = new X509Certificate2(defaultCert, "pass@w0rd1");
                }
                var rsaCrypto = (RSACryptoServiceProvider)this.Certificate.PublicKey.Key;
     
                int bufferSize = (rsaCrypto.KeySize / 8) - 11;
                byte[] buffer = new byte[bufferSize];
                //分段加密
                using (MemoryStream input = new MemoryStream(OriginalData))
                using (MemoryStream ouput = new MemoryStream())
                {
                    while (true)
                    {
                        int readLine = input.Read(buffer, 0, bufferSize);
                        if (readLine <= 0)
                        {
                            break;
                        }
                        byte[] temp = new byte[readLine];
                        Array.Copy(buffer, 0, temp, 0, readLine);
                        byte[] encrypt = rsaCrypto.Encrypt(temp, false);
                        ouput.Write(encrypt, 0, encrypt.Length);
                    }
                    return ouput.ToArray();
                }
            }
     
            public string EncryptString(string OriginalString)
            {
                if (OriginalString == null) throw new ArgumentNullException("OriginalString");
     
                var originalData = this.Encoding.GetBytes(OriginalString);
                var encryptData = this.Encryptor(originalData);
                var base64 = Convert.ToBase64String(encryptData);
                return base64;
            }
     
            public void EncryptFile(string OriginalFile, string EncrytpFile)
            {
                using (FileStream originalStream = new FileStream(OriginalFile, FileMode.Open, FileAccess.Read))
                using (FileStream encrytpStream = new FileStream(EncrytpFile, FileMode.Create, FileAccess.Write))
                {
                    //加密
                    var dataByteArray = new byte[originalStream.Length];
                    originalStream.Read(dataByteArray, 0, dataByteArray.Length);
                    var encryptData = this.Encryptor(dataByteArray);
                    //寫檔
                    encrytpStream.Write(encryptData, 0, encryptData.Length);
                }
            }
     
            public byte[] Decryptor(byte[] EncryptDada)
            {
                if (EncryptDada == null) throw new ArgumentNullException("EncryptDada");
                if (EncryptDada.Length <= 0) throw new ArgumentOutOfRangeException("EncryptDada");
     
                if (this.Certificate == null)
                {
                    //使用資源檔裡的預設憑證
                    var defaultCert = RsaAndX509.Properties.Resources.artag_certnew;
                    this.Certificate = new X509Certificate2(defaultCert, "pass@w0rd1");
                }
     
                var rsaCrypto = (RSACryptoServiceProvider)this.Certificate.PrivateKey;
     
                int keySize = rsaCrypto.KeySize / 8;
                byte[] buffer = new byte[keySize];
     
                using (MemoryStream input = new MemoryStream(EncryptDada))
                using (MemoryStream output = new MemoryStream())
                {
                    while (true)
                    {
                        int readLine = input.Read(buffer, 0, keySize);
                        if (readLine <= 0)
                        {
                            break;
                        }
                        byte[] temp = new byte[readLine];
                        Array.Copy(buffer, 0, temp, 0, readLine);
                        byte[] decrypt = rsaCrypto.Decrypt(temp, false);
                        output.Write(decrypt, 0, decrypt.Length);
                    }
                    return output.ToArray();
                }
            }
     
            public string DecryptString(string EncryptString)
            {
                if (EncryptString == null) throw new ArgumentNullException("EncryptString");
                var encryptData = Convert.FromBase64String(EncryptString);
                var decryptData = this.Decryptor(encryptData);
                var decryptString = this.Encoding.GetString(decryptData);
                return decryptString;
            }
     
            public void DecryptFile(string EncrytpFile, string DecrytpFile)
            {
                if (EncrytpFile == null) throw new ArgumentNullException("EncrytpFile");
                if (DecrytpFile == null) throw new ArgumentNullException("DecrytpFile");
                using (FileStream encrytpStream = new FileStream(EncrytpFile, FileMode.Open, FileAccess.Read))
                using (FileStream decrytpStream = new FileStream(DecrytpFile, FileMode.Create, FileAccess.Write))
                {
                    //解密
                    var dataByteArray = new byte[encrytpStream.Length];
                    encrytpStream.Read(dataByteArray, 0, dataByteArray.Length);
                    var decryptData = this.Decryptor(dataByteArray);
                    //寫檔
                    decrytpStream.Write(decryptData, 0, decryptData.Length);
                }
            }
        }
    }
    字串加密單元測試:
     [TestMethod()]
            public void EncryptStringTest()
            {
                RsaCryptService target = new RsaCryptService();
                string OriginalString =
    @"
    你同事剛開完會走出來,你想知道結果如何?你的朋友願意幫你忙嗎?你的部屬是否對你做的新安排感到滿意?《看穿人心的問話術》教你透過五大技巧探知對方的真實感受,不論他們的口風有多緊!
    技巧一:他願意幫忙嗎?請用「得寸進尺」法
    研究顯示,在你想請某人幫你一個忙之前,先對他提出一個簡單容易達成的小小要求,在他幫忙之後,隨即給予感謝或表彰。事後你再提出原本要請他做的事情,或是尋求他更多的幫助,他就比較有可能會全盤接受。
    佛德門和佛瑞賽(Freedman and Fraser)曾經提到一項實驗,他們將受訪住戶隨機分成兩組,他們直接向第一組住戶提出請求,要在他們在前院樹立一個大型的「小心駕駛」告示牌,結果只有百分之十七的人同意。至於第二組住戶,則先被要求在窗戶上貼一個三吋大小,上面寫著「當個安全駕駛人」的標示,幾乎所有的住戶都同意接受。幾週後,測試者再向第二組住戶提出請求,要他們跟第一組住戶一樣,在前院設置大型標示,最後竟有高達百分之七十六的住戶同意此項要求。
    技巧二:他贊成還是反對?改問他心情好不好
    想知道他的真實想法,可以問他不相干的問題。如果他的話中似乎隱含著好兆頭的跡象,那麼就表示他對此事看法樂觀。然而,若他說這件事似乎是負面結果的前兆,那麼就表示他的看法頗為悲觀。
    例如,你的同事約翰最近在為一個新的秘密計畫爭取支援,剛剛開完相關會議走出來。他不能透露任何會議細節,以避免別人從他的神情中,窺探公司對其計畫的支持程度,他一直盡可能地維持面無表情的狀態。
    ";
                string expected = string.Empty;
                string actual;
                actual = target.EncryptString(OriginalString);
                Assert.AreNotEqual(expected, actual);
            }
    字串解密單元測試:
    [TestMethod()]
            public void DecryptStringTest()
            {
                RsaCryptService target = new RsaCryptService();
                string EncryptString = "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";
                string expected =
    @"
    你同事剛開完會走出來,你想知道結果如何?你的朋友願意幫你忙嗎?你的部屬是否對你做的新安排感到滿意?《看穿人心的問話術》教你透過五大技巧探知對方的真實感受,不論他們的口風有多緊!
    技巧一:他願意幫忙嗎?請用「得寸進尺」法
    研究顯示,在你想請某人幫你一個忙之前,先對他提出一個簡單容易達成的小小要求,在他幫忙之後,隨即給予感謝或表彰。事後你再提出原本要請他做的事情,或是尋求他更多的幫助,他就比較有可能會全盤接受。
    佛德門和佛瑞賽(Freedman and Fraser)曾經提到一項實驗,他們將受訪住戶隨機分成兩組,他們直接向第一組住戶提出請求,要在他們在前院樹立一個大型的「小心駕駛」告示牌,結果只有百分之十七的人同意。至於第二組住戶,則先被要求在窗戶上貼一個三吋大小,上面寫著「當個安全駕駛人」的標示,幾乎所有的住戶都同意接受。幾週後,測試者再向第二組住戶提出請求,要他們跟第一組住戶一樣,在前院設置大型標示,最後竟有高達百分之七十六的住戶同意此項要求。
    技巧二:他贊成還是反對?改問他心情好不好
    想知道他的真實想法,可以問他不相干的問題。如果他的話中似乎隱含著好兆頭的跡象,那麼就表示他對此事看法樂觀。然而,若他說這件事似乎是負面結果的前兆,那麼就表示他的看法頗為悲觀。
    例如,你的同事約翰最近在為一個新的秘密計畫爭取支援,剛剛開完相關會議走出來。他不能透露任何會議細節,以避免別人從他的神情中,窺探公司對其計畫的支持程度,他一直盡可能地維持面無表情的狀態。
    ";
                string actual;
                actual = target.DecryptString(EncryptString);
                Assert.AreEqual(expected, actual);
            }

     

     

     

     

     

     

     

     

  • 相关阅读:
    python自动化之利用configparser库获取配置文件中的section,option,value值
    python自动化之pymysql库连接mysql数据库封装成类
    python中封装pymysql库连接mysql数据库
    python自动化之requests库封装
    OS模块获取文件相对路径
    元素定位之xpath定位详解
    Jmeter工具-连接postgresql数据库+提取参数并应用到下个接口中
    JDK安装与环境变量配置
    python使用psycopg2连接postgresql数据库
    SQL的in的参数化查询
  • 原文地址:https://www.cnblogs.com/wuyifu/p/3217247.html
Copyright © 2011-2022 走看看