Rsa - Tạo Key Pairs Để Mã Hóa - Encrypt Và Giải Mã - Decrypt

Thảo luận trong 'Tổng Hợp' bắt đầu bởi Pussy, Tháng 5 5, 2017.

  1. Pussy

    Pussy New Member Chuyển tiền Tìm chủ đề

    Bài viết:
    Tìm chủ đề
    950
    Trong mật mã học, RSA là một thuật toán mật mã hóa bất đối xứng (khóa công khai). Đây là thuật toán đầu tiên phù hợp với việc tạo ra chữ ký điện tử đồng thời với việc mã hóa. Nó đánh dấu một sự tiến bộ vượt bậc của lĩnh vực mật mã học trong việc sử dụng khóa công cộng. RSA đang được sử dụng phổ biến trong thương mại điện tử và được cho là đảm bảo an toàn với điều kiện độ dài khóa đủ lớn.

    Thuật toán được Ron Rivest, Adi ShamirLen Adleman mô tả lần đầu tiên vào năm 1977 tại Học viện Công nghệ Massachusetts (MIT). Tên của thuật toán lấy từ 3 chữ cái đầu của tên 3 tác giả.

    Thuật toán RSA có hai khóa: khóa công khai (hay khóa công cộng) và khóa bí mật (hay khóa cá nhân). Mỗi khóa là những số cố định sử dụng trong quá trình mã hóa và giải mã. Khóa công khai được công bố rộng rãi cho mọi người và được dùng để mã hóa. Những thông tin được mã hóa bằng khóa công khai chỉ có thể được giải mã bằng khóa bí mật tương ứng. Nói cách khác, mọi người đều có thể mã hóa nhưng chỉ có người biết khóa cá nhân (bí mật) mới có thể giải mã được.

    Ta có thể mô phỏng trực quan một hệ mật mã khoá công khai như sau: Bob muốn gửi cho Alice một thông tin mật mà Bob muốn duy nhất Alice có thể đọc được. Để làm được điều này, Alice gửi cho Bob một chiếc hộp có khóa đã mở sẵn và giữ lại chìa khóa. Bob nhận chiếc hộp, cho vào đó một tờ giấy viết thư bình thường và khóa lại (như loại khoá thông thường chỉ cần sập chốt lại, sau khi sập chốt khóa ngay cả Bob cũng không thể mở lại được-không đọc lại hay sửa thông tin trong thư được nữa). Sau đó Bob gửi chiếc hộp lại cho Alice. Alice mở hộp với chìa khóa của mình và đọc thông tin trong thư. Trong ví dụ này, chiếc hộp với khóa mở đóng vai trò khóa công khai, chiếc chìa khóa chính là khóa bí mật.

    [​IMG]

    Cài đặt thuật toán mã hóa bất đối xứng RSA dùng C#:

    Mã:
    using System;
    using System.Security.Cryptography;
    using System.Text;
    
    namespace Security.Cryptography
    {
        /// <summary>
        /// Performs asymmetric encryption and decryption using the implementation of
        /// the System.Security.Cryptography.RSA algorithm provided by the cryptographic
        /// service provider (CSP). This class cannot be inherited.
        /// Reference:
        /// http://jamiekurtz.com/2013/01/14/asp-net-web-api-security-basics/
        /// http://blogs.msdn.com/b/alejacma/archive/2008/10/23/how-to-generate-key-pairs-encrypt-and-decrypt-data-with-net-c.aspx
        /// http://www.technical-recipes.com/2013/using-rsa-to-encrypt-large-data-files-in-c/
        /// http://codebetter.com/johnvpetersen/2012/04/02/making-your-asp-net-web-apis-secure/
        /// </summary>
        public sealed class RSACryptography
        {
    
            #region Private Fields
    
            private const int KEY_SIZE = 2048; // The size of the RSA key to use in bits.
            private bool fOAEP = false;
            private RSACryptoServiceProvider rsaProvider = null;
    
            #endregion
    
            #region Constructors
    
            /// <summary>
            /// Initializes a new instance of the System.Security.Cryptography.RSACryptoServiceProvider
            /// class with the predefined key size and parameters.
            /// </summary>
            public RSACryptography()
            {
            }
    
            #endregion
    
            #region Private Methods
    
            /// <summary>
            /// Initializes a new instance of the System.Security.Cryptography.CspParameters class.
            /// </summary>
            /// <returns>An instance of the System.Security.Cryptography.CspParameters class.</returns>
            private CspParameters GetCspParameters()
            {
                // Create a new key pair on target CSP
                CspParameters cspParams = new CspParameters();
                cspParams.ProviderType = 1; // PROV_RSA_FULL
                // cspParams.ProviderName; // CSP name
                // cspParams.Flags = CspProviderFlags.UseArchivableKey;
                cspParams.KeyNumber = (int)KeyNumber.Exchange;
    
                return cspParams;
            }
    
            /// <summary> 
            /// Gets the maximum data length for a given key 
            /// </summary>        
            /// <param name="keySize">The RSA key length 
            /// <returns>The maximum allowable data length</returns> 
            public int GetMaxDataLength()
            {
                if (fOAEP)
                    return ((KEY_SIZE - 384) / 8) + 7;
                return ((KEY_SIZE - 384) / 8) + 37;
            }
    
            /// <summary> 
            /// Checks if the given key size if valid 
            /// </summary>        
            /// <param name="keySize">The RSA key length 
            /// <returns>True if valid; false otherwise</returns> 
            public static bool IsKeySizeValid()
            {
                return KEY_SIZE >= 384 &&
                       KEY_SIZE <= 16384 &&
                       KEY_SIZE % 8 == 0;
            }
    
            #endregion
    
            #region Public Methods
    
            /// <summary>
            /// Generate a new RSA key pair.
            /// </summary>
            /// <param name="publicKey">An XML string containing ONLY THE PUBLIC RSA KEY.</param>
            /// <param name="privateKey">An XML string containing a PUBLIC AND PRIVATE RSA KEY.</param>
            public void GenerateKeys(out string publicKey, out string privateKey)
            {
                try
                {
                    CspParameters cspParams = GetCspParameters();
                    cspParams.Flags = CspProviderFlags.UseArchivableKey;
    
                    rsaProvider = new RSACryptoServiceProvider(KEY_SIZE, cspParams);
    
                    // Export public key
                    publicKey = rsaProvider.ToXmlString(false);
    
                    // Export private/public key pair
                    privateKey = rsaProvider.ToXmlString(true);
                }
                catch (Exception ex)
                {
                    // Any errors? Show them
                    throw new Exception("Exception generating a new RSA key pair! More info: " + ex.Message);
                }
                finally
                {
                    // Do some clean up if needed
                }
    
            } // GenerateKeys method
    
            /// <summary>
            /// Encrypts data with the System.Security.Cryptography.RSA algorithm.
            /// </summary>
            /// <param name="publicKey">An XML string containing the public RSA key.</param>
            /// <param name="plainText">The data to be encrypted.</param>
            /// <returns>The encrypted data.</returns>
            public string Encrypt(string publicKey, string plainText)
            {
                if (string.IsNullOrWhiteSpace(plainText))
                    throw new ArgumentException("Data are empty");
    
                int maxLength = GetMaxDataLength();
                if (Encoding.Unicode.GetBytes(plainText).Length > maxLength)
                    throw new ArgumentException("Maximum data length is " + maxLength / 2);
    
                if (!IsKeySizeValid())
                    throw new ArgumentException("Key size is not valid");
    
                if (string.IsNullOrWhiteSpace(publicKey))
                    throw new ArgumentException("Key is null or empty");
    
                byte[] plainBytes = null;
                byte[] encryptedBytes = null;
                string encryptedText = "";
    
                try
                {
                    CspParameters cspParams = GetCspParameters();
                    cspParams.Flags = CspProviderFlags.NoFlags;
    
                    rsaProvider = new RSACryptoServiceProvider(KEY_SIZE, cspParams);
    
                    // [1] Import public key
                    rsaProvider.FromXmlString(publicKey);
    
                    // [2] Get plain bytes from plain text
                    plainBytes = Encoding.Unicode.GetBytes(plainText);
    
                    // Encrypt plain bytes
                    encryptedBytes = rsaProvider.Encrypt(plainBytes, false);
    
                    // Get encrypted text from encrypted bytes
                    // encryptedText = Encoding.Unicode.GetString(encryptedBytes); => NOT WORKING
                    encryptedText = Convert.ToBase64String(encryptedBytes);
                }
                catch (Exception ex)
                {
                    // Any errors? Show them
                    throw new Exception("Exception encrypting file! More info: " + ex.Message);
                }
                finally
                {
                    // Do some clean up if needed
                }
    
                return encryptedText;
    
            } // Encrypt method
    
            /// <summary>
            /// Decrypts data with the System.Security.Cryptography.RSA algorithm.
            /// </summary>
            /// <param name="privateKey">An XML string containing a public and private RSA key.</param>
            /// <param name="encryptedText">The data to be decrypted.</param>
            /// <returns>The decrypted data, which is the original plain text before encryption.</returns>
            public string Decrypt(string privateKey, string encryptedText)
            {
                if (string.IsNullOrWhiteSpace(encryptedText))
                    throw new ArgumentException("Data are empty");
    
                if (!IsKeySizeValid())
                    throw new ArgumentException("Key size is not valid");
    
                if (string.IsNullOrWhiteSpace(privateKey))
                    throw new ArgumentException("Key is null or empty");
    
                byte[] encryptedBytes = null;
                byte[] plainBytes = null;
                string plainText = "";
    
                try
                {
                    CspParameters cspParams = GetCspParameters();
                    cspParams.Flags = CspProviderFlags.NoFlags;
    
                    rsaProvider = new RSACryptoServiceProvider(KEY_SIZE, cspParams);
    
                    // [1] Import private/public key pair
                    rsaProvider.FromXmlString(privateKey);
    
                    // [2] Get encrypted bytes from encrypted text
                    // encryptedBytes = Encoding.Unicode.GetBytes(encryptedText); => NOT WORKING
                    encryptedBytes = Convert.FromBase64String(encryptedText);
    
                    // Decrypt encrypted bytes
                    plainBytes = rsaProvider.Decrypt(encryptedBytes, false);
    
                    // Get decrypted text from decrypted bytes
                    plainText = Encoding.Unicode.GetString(plainBytes);
                }
                catch (Exception ex)
                {
                    // Any errors? Show them
                    throw new Exception("Exception decrypting file! More info: " + ex.Message);
                }
                finally
                {
                    // Do some clean up if needed
                }
    
                return plainText;
    
            } // Decrypt method
    
            #endregion
    
        }
    }
    Sử dụng thuật toán mã hóa RSA:

    Mã:
    public string GenerateKeys()
    {
        RSACryptography RSA = new RSACryptography();
        string publicKey, privateKey;
    
        // Generate RSA key pair
        RSA.GenerateKeys(out publicKey, out privateKey);
    
        string plainText = "93f99709-ce56-42a9-af7e-1d72c011c2dd";// Guid.NewGuid().ToString();
    
        // Encrypt
        string encryptedText = RSA.Encrypt(publicKey, plainText);
    
        // Decrypt
        string decryptedText = RSA.Decrypt(privateKey, encryptedText);
    
        return "<b>Token:</b> " + Server.HtmlEncode(plainText) + "<br />" + "<b>Public key:</b> " + Server.HtmlEncode(publicKey) + "<br />" + "<b>Private key:</b> " + Server.HtmlEncode(privateKey) + "<br />" + "<b>Encrypted text:</b> " + Server.HtmlEncode(encryptedText) + "<br />" + "<b>Decrypted text:</b> " + Server.HtmlEncode(decryptedText);
    }
     
    Last edited by a moderator: Tháng 5 21, 2017
  2. Đang tải...
Trả lời qua Facebook

Chia sẻ trang này