首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 程式設計總結(七):資料加密全解析——雜湊、對稱與非對稱加密

     編輯:關於C#

前言

資料加密是資訊安全的基石。本文系統整理雜湊演算法(MD5、SHA1)、對稱加密(DES、AES)、非對稱加密(RSA)的原理、優缺點與 C# 實作,並針對已知弱點給出建議。

一、摘要演算法

摘要演算法(雜湊/散列)將任意長度資料映射為固定長度指紋,具單向不可逆、雪崩效應特性。常用於密碼儲存、完整性校驗、數位簽名。注意:MD5 已被破解,建議改用 SHA256 或更強演算法。

1. MD5

輸出 128 位(16 位元組),常以 32 字元十六進位字串呈現。

public static string EncryptByMD5(string input) {
    using (MD5 md5 = MD5.Create()) {
        byte[] data = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
        StringBuilder sb = new StringBuilder();
        foreach (byte b in data) sb.Append(b.ToString("x2"));
        return sb.ToString();
    }
}

2. SHA1

輸出 160 位(20 位元組),比 MD5 強但亦已不建議用於高安全性場合。

public static string EncryptBySHA1(string input) {
    using (SHA1 sha = SHA1.Create()) {
        byte[] bytes = Encoding.Unicode.GetBytes(input);
        byte[] result = sha.ComputeHash(bytes);
        return BitConverter.ToString(result).Replace("-", "");
    }
}

二、對稱加密

加密解密使用同一把金鑰。優點:速度快、效率高,適合大量資料。缺點:金鑰管理困難、缺乏簽名功能。DES 已被破解,建議使用 3DES 或 AES。

1. DES

56 位金鑰,64 位分組,16 輪迭代。現今極易暴力破解,僅供非機密場合參考。

public static string EncryptString(string input, string sKey) {
    byte[] data = Encoding.UTF8.GetBytes(input);
    using (DESCryptoServiceProvider des = new DESCryptoServiceProvider()) {
        des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
        des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
        ICryptoTransform encryptor = des.CreateEncryptor();
        byte[] result = encryptor.TransformFinalBlock(data, 0, data.Length);
        return BitConverter.ToString(result);
    }
}
public static string DecryptString(string input, string sKey) {
    string[] sInput = input.Split('-');
    byte[] data = new byte[sInput.Length];
    for (int i = 0; i < sInput.Length; i++) data[i] = byte.Parse(sInput[i], NumberStyles.HexNumber);
    using (DESCryptoServiceProvider des = new DESCryptoServiceProvider()) {
        des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
        des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
        ICryptoTransform decryptor = des.CreateDecryptor();
        byte[] result = decryptor.TransformFinalBlock(data, 0, data.Length);
        return Encoding.UTF8.GetString(result);
    }
}

2. AES (Rijndael)

美國聯邦政府採用標準,支援 128/192/256 位金鑰,取代 DES 成為主流對稱加密。

// 需定義 static readonly byte[] AES_IV = ... (16 位元組)
public static string EncryptByAES(string input, string key) {
    byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 32)); // 256 位
    using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider()) {
        aes.Key = keyBytes; aes.IV = AES_IV;
        using (MemoryStream ms = new MemoryStream())
        using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
        using (StreamWriter sw = new StreamWriter(cs)) {
            sw.Write(input);
        }
        return BitConverter.ToString(ms.ToArray());
    }
}
public static string DecryptByAES(string input, string key) {
    string[] sInput = input.Split('-');
    byte[] inputBytes = new byte[sInput.Length];
    for (int i = 0; i < sInput.Length; i++) inputBytes[i] = byte.Parse(sInput[i], NumberStyles.HexNumber);
    byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 32));
    using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider()) {
        aes.Key = keyBytes; aes.IV = AES_IV;
        using (MemoryStream ms = new MemoryStream(inputBytes))
        using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Read))
        using (StreamReader sr = new StreamReader(cs)) {
            return sr.ReadToEnd();
        }
    }
}

對稱加密原理圖

三、非對稱加密

使用公鑰/私鑰對。公鑰加密、私鑰解密(機密性);私鑰加密、公鑰解密(簽名/身分驗證)。優點:無需預先交換金鑰、金鑰管理容易、支援防抵賴。缺點:運算速度慢,不適合大量資料。

主要演算法

RSA、ElGamal、ECC(橢圓曲線)等。RSA 最常見,基於大數質因數分解困難性。

RSA 加解密實作

public static string EncryptByRSA(string plaintext, string publicKey) {
    UnicodeEncoding converter = new UnicodeEncoding();
    byte[] data = converter.GetBytes(plaintext);
    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) {
        rsa.FromXmlString(publicKey);
        byte[] encrypted = rsa.Encrypt(data, false);
        return Convert.ToBase64String(encrypted);
    }
}
public static string DecryptByRSA(string ciphertext, string privateKey) {
    UnicodeEncoding converter = new UnicodeEncoding();
    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) {
        rsa.FromXmlString(privateKey);
        byte[] data = Convert.FromBase64String(ciphertext);
        byte[] decrypted = rsa.Decrypt(data, false);
        return converter.GetString(decrypted);
    }
}

場景1:公鑰加密私鑰解密 場景2:私鑰加密公鑰解密

完整原始碼下載:EncriptSample.zip

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved