Reputation: 499
I've been developing an ASP.NET WEB API RESTFUL service to be consumed by an angularjs client. Now, I'm making it secure and I've decided to implemement RSA encryption to get it. So, in the server side I'm using RSACryptoServiceProvider methods with both a public and private key stored in a file. It's nearly enough, but, in the first call of the client, it sends an string of username and password to be authenticated and get a token so I must encrypt that call.
Does anybody know about any tutorial or manual about how to implement something similar in JS to what I'm using in C#?
Here is the piece of code of encryption in the 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
}
}
Thanks in advance.
Upvotes: 0
Views: 1594
Reputation: 5108
@m.dorian - This is a very bad idea! Please do not try to implement this in any way if you value security and best practices. I would suggest that you read up on the subject thoroughly. In addition, you should ALWAYS hash your user's password and not encrypt them. Passwords should be one-way hashed etc etc.
If you don't know the specifics of data security, I would recommend that you take a step back and either speak to someone that knows what they're doing, or you educate yourself. Especially after all the data compromises reported in the last couple of years. Useful post by Troy Hunt can be found here and this should only be the start!
Upvotes: 1
Reputation: 6376
An new API, Web Cryptography API, is currently in draft status but according to MDN it can be used in in the latest versions of almost every major browser.
However, I'm not sure what you're trying to achieve? You said you want client-side encryption of the username and password, but why aren't you just using TLS to encrypt all the traffic? Or are you using the username & password to generate a private key with which to encrypt and decrypt the data client-side so you only have to store the public key on the server?
And a side-note, you are storing the encryption keys in files. How secure are you storing them? When somebody steals the keys all the data is out in the open.
Upvotes: 0