2014-12-03 93 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