Simplest Method of Encrypting a String in .NET without MachineKey [duplicate] - c#

This question already has answers here:
Encrypt and decrypt a string in C#? [closed]
(29 answers)
Simple insecure two-way data "obfuscation"?
(17 answers)
Closed 7 years ago.
I am currently encrypting strings as follows:
public static string Encrypt(this string DecryptedValue)
{
if (string.IsNullOrWhiteSpace(DecryptedValue)) { return string.Empty; }
return HttpServerUtility.UrlTokenEncode(MachineKey.Protect(Encoding.UTF8.GetBytes(DecryptedValue.Trim())));
}
public static string Decrypt(this string EncryptedValue)
{
if (string.IsNullOrWhiteSpace(EncryptedValue)) { return string.Empty; }
return Encoding.UTF8.GetString(MachineKey.Unprotect(HttpServerUtility.UrlTokenDecode(EncryptedValue)));
}
However, when I move the production database to a development server (to test a new version before I deploy), these functions are unable to decrypt data already stored in the database (I assume that this is because of my usage of the MachineKey).
Is there some way that I could modify the above extensions so that I could encrypt/decrypt the same database on multiple machines without writing something complicated?

Assuming you are talking about asp.net, you can try keeping your code and change configuration in web.config instead.
Specify same machine key and algorithms as in production server.
See https://msdn.microsoft.com/en-us/library/w8h3skw9(v=vs.100).aspx for reference.
If the key is specified in web.config file, it should override the real machine key in your development enviroment just for your application.

Related

How can i get the PC Name of a client Machine [duplicate]

This question already has answers here:
How to get client's computer name
(3 answers)
Closed 7 months ago.
The community reviewed whether to reopen this question 7 months ago and left it closed:
Original close reason(s) were not resolved
There is any way to get the PC Name of a client Machine in web application, who is working in different Network, in c# asp.net ?
"This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server. showing this error.
By doing the answer given in this
How to get client's computer name ,
I think this will help you:
string clienIp = Request.UserHostName;
string computenMame = CompName(clientIp);
public static string CompName(string clienIp)
{
IPAddress myIP = IPAddress.Parse(clienIp);
IPHostEntry GetIPHost = Dns.GetHostEntry(myIP);
List<string> compName =
GetIPHost.HostName.ToString().Split('.').ToList();
return compName.First();
}

Store data in C# application [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have a message prompting the user to upgrade some equipment connected to the computer. I want to let the user disable this message in the future, by checking a box before pressing cancel.
How can I store this user option, so that next time the program executes I can avoid showing this message based on the user choice made in the last session of the application?
The two cleanest ways are the Registry and User Settings.
I prefer User Settings because:
they're in XML (no registry hacking required)
a lot of the grunt work is done by the framework
User settings persist across upgrades automatically with ClickOnce
All you need to do is go to the Setings tab in the project's properties, add a setting, and set it's type to User.
Then just save the settings after changing them:
Properties.Settings.Default.ShowDisconnectMessage = false;
Properties.Settings.Default.Save();
The registry works similarly but it requires a bit more code and is not strongly-typed:
RegistryKey key = Registry.CurrentUser.OpenSubKey("Software",true);
Key = key.OpenSubKey("AppName", true);
key.SetValue("ShowDisconnectMessage ", "false");
You'll need to make the messages in your application use a custom form. That form will need to show the message as well as have the check box. Then you'll want to store that information somewhere. I'm going to say in the application configuration file.
So, to save the data in the configuration file, first build a few extension methods to make it easier:
public static class Extensions
{
public static void SetValue(this KeyValueConfigurationCollection o,
string key,
string val)
{
if (!o.AllKeys.Contains(key)) { o.Add(key, val); }
else { o[key].Value = val; }
}
public static string GetValue(this NameValueCollection o,
string key,
object defaultVal = null)
{
if (!o.AllKeys.Contains(key)) { return Convert.ToString(defaultVal); }
return o[key];
}
}
Then, when you want to read that value to determine if you ought to show the message, do this:
var val = (bool)ConfigurationManager.AppSettings.GetValue("ShowTheMessage");
and then when you want to save the value, do this:
var config = ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.None);
var app = config.AppSettings.Settings;
app.SetValue("ShowTheMessage", checkBox.Checked);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");

What's a good way to store unchanging variables in a C# project?

I'm just learning C#, so pardon my n00bness, please.
We use Visual Studio 2012 to put together a C#/Selenium project for automated testing.
We have three credit card processors.
I want to store the login credentials, test settings, and test payment items for each processor. I could do this in Python in a minute, using a dict:
processorCreds = {
'ProcOne': {
'website': '[url]',
'username': '[username]',
'password': '[password]'
},
'ProcTwo': {
'website': '[url]',
'username': '[username]',
'password': '[password]'
},
}
And then I'd just call it when I need it:
def openProcessor(procName):
urllib2.urlopen(processorCreds[procName]['website'])
openProcessor('ProcTwo')
I want this in C#, basically. I will only rarely need to change these credentials, and they'll be used in multiple test cases, so I want to be able to pull the information wherever I need it.
What would be the best way for me to put this together? Should I use an XML file, or can this be in a class, or...?
[EDIT] The alternative I see is that we set the variables each time we have a test case, which doesn't seem... object-oriented. Or, I suppose I could put the variables on the [Processor]Portal.cs pages... I was just hoping for a way to put alla this in one place with a minimum of fuss, for our occasional "this works for every processor" tests.
(Also this is totally test data, and would be accessible to the same folk who can already see it now, so I'm not worried.)
.NET offers many ways of storing constant or nearly constant data: you have a choice among multiple ways of reading XML files, configuration files, resource files with your own format, and so on. If you would like to define a structure like yours in code, you can use IDictionary:
internal static readonly IDictionary<string,dynamic> ProcessorCreds =
new Dictionary<string,dynamic> {
{"ProcOne", new {
Website = "[url]",
Username = "[username]",
Password = "[password]"
},
{"ProcTwo", new {
Website = "[url]",
Username = "[username]",
Password = "[password]"
}
};
This creates an instance of Dictionary that maps string objects to anonymous objects with three properties - Website, Username, and Password. Since objects that go in belong to an anonymous class (note the lack of class name between new and the opening curly brace) the value type of the dictionary is defined as dynamic. This would let you add more attributes in the future without changing anything else.
You can use ProcessorCreds like this:
urlopen(ProcessorCreds[procName].Website);
You can put them in App.Config( Web.Config) in the appsettings section and use the configurationmanager to get he values as shown in the example below
<appSettings>
<add key="username" value="me" />
<add key="password" value="getmein" />
</appSettings>
In the code you will have the following
string username=ConfigurationManager.AppSettings["username"];
Using C# or Python does not change the answer to this question substantially. If using a mutable in-memory data structure like a dictionary did the trick fine for you in Python, then you can just do the same in C#.
A similar answer uses dynamic, but it is more idiomatic and there are many advantages in C# to favor using static typing, like so:
public class Processor {
public Uri Website { get; private set; }
public string Username { get; private set; }
public string Password { get; private set; }
public Processor(Uri website, string username, string password) {
Website = website;
Username = username;
Password = password;
}
}
var processorCreds = new Dictionary<string, Processor> {
{ "ProcOne", new Processor(new Uri("[url]"), "[username]", "[password]") },
{ "ProcTwo", new Processor {new Uri("[url]"), "[username]", "[password]") }
};
which case be used as
processorCreds["ProcOne"].Website
There are a lot of different ways to do this. You could store the data in a static readonly dictionary.
public static readonly Dictionary<int, int> MY_DICTIONARY;
And place this inside a static class available throughout your project.
You could also store data in the Properties settings.settings file.
Generally, in my C# code I try to avoid global data and instead pass information when it is needed. This allows for code that is more easily tested.
Your question has more security and procedural implications than technical.
Since you're saving usernames and passwords for payment processing, there're all kinds of risks to storing these where they are publicly available. Do you need PCI compliance in your business? Given that this is security information, don't you want to keep them under lock-and-key to some extent? Perhaps keep them in a database, or encrypted in some way.
If there's no such issue, your appConfig file is probably the best bet: you can define them in your project, and retrieve them using the ConfigurationManager class. The will be stored in the XML file that is deployed along with your application. In plain text.
Put them in a static dynamic variable - this is the most pythonish way to do it, although it's not idiomatic c#
static dynamic processorCreds =new {
ProcOne= new {
website= "[url]",
username= "[username]",
password= "[password]"
},
ProcTwo= new {
website= "[url]",
username= "[username]",
password= "[password]"
},
}
You can then access it using var s = (string) processorCreds.ProcTwo.website;

How to detect RDC from C#.net [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do you retrieve a list of logged-in/connected users in .NET?
I have hosted WCF service in IIS on a machine. Now i want to write a method in the service by which I could detect whether the hosted machine is currently being used by any Remote Desktop Connection or not.
Is there any other better way to find out this, and what are the exact code APIs by which RDC connection is detected.
I am using C#.net, framework 3.5
There are two options for you. You can use the P/Invoke Calls to the WSTAPI library however it is easy to mess stuff up and get resource leaks.
Your other option is to use the WTSAPI wrapper library Cassia. I have used that before and it is easy to use and the classes are fairly self documenting.
In Cassia your function would simply be
public bool IsComputerUsedByTS()
{
var tsMgr = new TerminalServicesManager();
var localSvr = tsMgr.GetLocalServer();
var sessions = localSvr.GetSessions();
foreach(var session in sessions)
{
if(session.ConnectionState == ConnectionState.Active ||
session.ConnectionState == ConnectionState.Connected) //Add more states you want to check for as needed
{
return true;
}
}
return false;
}
I did not test the above, and I think "active" is used if you are a console session where "Connected" is for RDP sessions. there are lot more states, look at the enum for all of the options.
RDP servers listen on port 3389 by default (but can be configured differently).
Therefore (even not being 100% reliable) this can be used to check any active RDP connections.
bool inUse = IPGlobalProperties.GetIPGlobalProperties()
.GetActiveTcpConnections()
.Any(tcp => tcp.LocalEndPoint.Port == 3389);
EDIT
I added #t3hn00b's suggestion.
int port = 3389;
using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(#"SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp", false))
{
if (key != null)
{
object value = key.GetValue("PortNumber");
if (value != null) port = Convert.ToInt32(value);
}
}
namespace: System.Net.NetworkInformation

CAPICOM Decrypt() errors with "ASN1 bad tag value met"

I have a large amount of data encrypted with the CAPICOM library through our legacy VB6 applications.
I need to access this data from a .Net 3.5 app but am getting the error: "ASN1 bad tag value met" when I call the Decrypt method. Google has been little help in tracking down decent code samples or explanations as to what this error means.
The following code is almost exactly a replication of what was happening in the VB6 code:
static string DecryptEncryptedText(string encryptedText, string secretKey)
{
var encryptedDataObj = new CAPICOM.EncryptedData();
encryptedDataObj.SetSecret(secretKey, CAPICOM_SECRET_TYPE.CAPICOM_SECRET_PASSWORD);
encryptedDataObj.Decrypt(encryptedText);
return encryptedDataObj.Content;
}
When I get this error it has been because I used the wrong key to decrypt. Have you checked the encoding of your secretKey? I suspect the data was encrypted with an ANSI string in VB6 and you are using a Unicode string in your new code.

Categories

Resources