2014-12-03 87 views
-1

我一直在開發一個ASP.NET WEB API RESTful服務,供angularjs客戶端使用。 現在,我正在使其安全,並且我決定實施RSA加密來獲得它。因此,在服務器端,我使用RSACryptoServiceProvider方法,將公鑰和私鑰存儲在文件中。這已經足夠了,但是在客戶端的第一次調用中,它會發送一串用戶名和密碼進行驗證並獲取令牌,因此我必須對該調用進行加密。在JS中相當於RSACryptoServiceProvider

有沒有人知道任何關於如何在JS中實現類似於我在C#中使用的教程或手冊?

這裏是WEB API中的一塊的加密代碼:

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

namespace MvcPrueba.Models 
{ 
public class Cryptography 
{ 
    #region Types 

    #region Enum 

    #endregion 

    #region Class 

    #endregion 

    #endregion 

    #region Variables 

    #endregion 

    #region Properties 

    #endregion 

    #region Constructors/Destructors 
    #region Constructors 
    protected Cryptography() 
    { 
    } 
    #region Instantiate 

    #endregion 

    #endregion 

    #region Destructors 
    public void Dispose() 
    { 
     throw new NotImplementedException(); 
    } 
    #endregion 

    #endregion 

    #region Class Logic 
    // Generate a new key pair 
    public static void GenerateKeys(string publicKeyFileName, string privateKeyFileName) 
    { 
     // Variables 
     CspParameters cspParams = null; 
     RSACryptoServiceProvider rsaProvider = null; 
     StreamWriter publicKeyFile = null; 
     StreamWriter privateKeyFile = null; 
     string publicKey = ""; 
     string privateKey = ""; 

     try 
     { 
      // Create a new key pair on target CSP 
      cspParams = new CspParameters(); 
      cspParams.ProviderType = 1; // PROV_RSA_FULL 
      //cspParams.ProviderName; // CSP name 
      cspParams.Flags = CspProviderFlags.UseArchivableKey; 
      cspParams.KeyNumber = (int)KeyNumber.Exchange; 
      rsaProvider = new RSACryptoServiceProvider(cspParams); 

      // Export public key 
      publicKey = rsaProvider.ToXmlString(false); 

      // Write public key to file 
      publicKeyFile = File.CreateText(publicKeyFileName); 
      publicKeyFile.Write(publicKey); 

      // Export private/public key pair 
      privateKey = rsaProvider.ToXmlString(true); 

      // Write private/public key pair to file 
      privateKeyFile = File.CreateText(privateKeyFileName); 
      privateKeyFile.Write(privateKey); 
     } 
     catch (Exception ex) 
     { 
      // Any errors? Show them 
      Console.WriteLine("Exception generating a new key pair! More info:"); 
      Console.WriteLine(ex.Message); 
     } 
     finally 
     { 
      // Do some clean up if needed 
      if (publicKeyFile != null) 
      { 
       publicKeyFile.Close(); 
      } 
      if (privateKeyFile != null) 
      { 
       privateKeyFile.Close(); 
      } 
     } 

    } // Keys 

    // Encrypt a file 
    public static void Encrypt(string publicKeyFileName, string plainFileName, string encryptedFileName) 
    { 
     // Variables 
     CspParameters cspParams = null; 
     RSACryptoServiceProvider rsaProvider = null; 
     StreamReader publicKeyFile = null; 
     StreamReader plainFile = null; 
     FileStream encryptedFile = null; 
     string publicKeyText = ""; 
     string plainText = ""; 
     byte[] plainBytes = null; 
     byte[] encryptedBytes = null; 

     try 
     { 
      // Select target CSP 
      cspParams = new CspParameters(); 
      cspParams.ProviderType = 1; // PROV_RSA_FULL 
      //cspParams.ProviderName; // CSP name 
      rsaProvider = new RSACryptoServiceProvider(cspParams); 

      // Read public key from file 
      publicKeyFile = File.OpenText(publicKeyFileName); 
      publicKeyText = publicKeyFile.ReadToEnd(); 

      // Import public key 
      rsaProvider.FromXmlString(publicKeyText); 

      // Read plain text from file 
      plainFile = File.OpenText(plainFileName); 
      plainText = plainFile.ReadToEnd(); 

      // Encrypt plain text 
      plainBytes = Encoding.Unicode.GetBytes(plainText); 
      encryptedBytes = rsaProvider.Encrypt(plainBytes, false); 

      // Write encrypted text to file 
      encryptedFile = File.Create(encryptedFileName); 
      encryptedFile.Write(encryptedBytes, 0, encryptedBytes.Length); 
     } 
     catch (Exception ex) 
     { 
      // Any errors? Show them 
      Console.WriteLine("Exception encrypting file! More info:"); 
      Console.WriteLine(ex.Message); 
     } 
     finally 
     { 
      // Do some clean up if needed 
      if (publicKeyFile != null) 
      { 
       publicKeyFile.Close(); 
      } 
      if (plainFile != null) 
      { 
       plainFile.Close(); 
      } 
      if (encryptedFile != null) 
      { 
       encryptedFile.Close(); 
      } 
     } 

    } // Encrypt 

    // Decrypt a file 
    public static void Decrypt(string privateKeyFileName, string encryptedFileName, string plainFileName) 
    { 
     // Variables 
     CspParameters cspParams = null; 
     RSACryptoServiceProvider rsaProvider = null; 
     StreamReader privateKeyFile = null; 
     FileStream encryptedFile = null; 
     StreamWriter plainFile = null; 
     string privateKeyText = ""; 
     string plainText = ""; 
     byte[] encryptedBytes = null; 
     byte[] plainBytes = null; 

     try 
     { 
      // Select target CSP 
      cspParams = new CspParameters(); 
      cspParams.ProviderType = 1; // PROV_RSA_FULL 
      //cspParams.ProviderName; // CSP name 
      rsaProvider = new RSACryptoServiceProvider(cspParams); 

      // Read private/public key pair from file 
      privateKeyFile = File.OpenText(privateKeyFileName); 
      privateKeyText = privateKeyFile.ReadToEnd(); 

      // Import private/public key pair 
      rsaProvider.FromXmlString(privateKeyText); 

      // Read encrypted text from file 
      encryptedFile = File.OpenRead(encryptedFileName); 
      encryptedBytes = new byte[encryptedFile.Length]; 
      encryptedFile.Read(encryptedBytes, 0, (int)encryptedFile.Length); 

      // Decrypt text 
      plainBytes = rsaProvider.Decrypt(encryptedBytes, false); 

      // Write decrypted text to file 
      plainFile = File.CreateText(plainFileName); 
      plainText = Encoding.Unicode.GetString(plainBytes); 
      plainFile.Write(plainText); 
     } 
     catch (Exception ex) 
     { 
      // Any errors? Show them 
      Console.WriteLine("Exception decrypting file! More info:"); 
      Console.WriteLine(ex.Message); 
     } 
     finally 
     { 
      // Do some clean up if needed 
      if (privateKeyFile != null) 
      { 
       privateKeyFile.Close(); 
      } 
      if (encryptedFile != null) 
      { 
       encryptedFile.Close(); 
      } 
      if (plainFile != null) 
      { 
       plainFile.Close(); 
      } 
     } 

    } // Decrypt 
    #endregion 
} 
} 

預先感謝。

+0

您不能使用SSL/TLS進行第一次請求嗎? – 2014-12-03 08:54:51

+0

好吧,我無法告訴你,如果我可以或不可以,我是這個世界的新手。我一直在谷歌搜索了一段時間,但我還沒有找到好的解釋或樣本:( – 2014-12-03 09:29:58

+0

如果您的服務器被入侵和您的文件,您的密鑰是存儲被盜竊會發生什麼?安全0 - 黑客1 – Chris 2014-12-03 11:17:58

回答

1

@ m.dorian - 這是一個非常糟糕的主意!如果您重視安全性和最佳實踐,請不要試圖以任何方式實施此操作。我建議你仔細閱讀這個主題。另外,你應該總是散列你的用戶密碼,而不是加密它們。密碼應該是單向散列等等。

如果您不知道數據安全的具體情況,我會建議您退後一步,告訴某個知道他們在做什麼的人,或者您教育自己。特別是在過去幾年中報告的所有數據妥協之後。有用的帖子Troy Hunt可以找到here,這應該只是一個開始!

+0

是的,沒錯,密碼必須散列。可以在服務器端存儲密碼哈希值,但它不能解決問題......黑客可以攔截哈希密碼d並且只是使用它散列,服務器會將它與散列存儲的密碼進行比較,並將其視爲有效:( – 2014-12-03 13:11:07

+0

因此,爲什麼您需要使用SSL端到端 – Chris 2014-12-03 13:35:14

+0

@Chris這實際上是一個非常好的主意。如果我的設備上有我的ca證書,我可以攔截此流量並嗅探呼叫。就像米。多裏安提到,我有客戶發送的簡單信息 - >我可以操縱數據。當然,沒有ABSOLUTE安全性,但我會結合這裏的努力:tls 1.2與客戶端證書,兩端證書固定,jsencrypt實際加密整個json。 – zaitsman 2015-01-01 13:31:02

0

新API,Web Cryptography API目前處於草稿狀態,但according to MDN它可以在幾乎所有主要瀏覽器的最新版本中使用。

但是,我不確定你想達到什麼目的?你說你想要用戶名和密碼的客戶端加密,但爲什麼你不使用TLS來加密所有的流量?或者您是否使用用戶名&密碼來生成一個私鑰,用於加密和解密數據客戶端,因此您只需將公鑰存儲在服務器上?

另外,您正在將加密密鑰存儲在文件中。你存儲它們有多安全?當有人竊取密鑰時,所有的數據都是公開的。

+0

那麼在文件中存儲密鑰的東西是非常糟糕的主意。也許我可以使用哈希方法來加密用戶名和密碼,並將它們存儲在服務器端進行加密? – 2014-12-03 08:04:49

+0

哈希不會阻止大多數密碼在文件被入侵時被盜。 – dandavis 2014-12-03 08:28:51