If one has a connectionstring in one's application, is there a way to encrypt the information it contains?
The connection string is created using the SqlConnectionStringBuilder object.
Or is it 'acceptable' that sensitive information is sent in plaintext to the server?
well you can use AES for example, to encrypt the data, send the encrypted connection string to the database computer. on that computer you need to build a listener that is getting the encrypted connection string and then decrypt it and connect to server. you need to build a softwere between the database computer and the user computer if you want to encrypt\decrypt all the data, but for the ConnectionString that the way...(encrypt -> send it to the server to a listener -> decrypt)
Hope it helps.
Amit.
Hope this helps.
Is it 'acceptable' that sensitive information is sent in plaintext to the server?
It depends on how much level of security you want for you application, as security critical apps might need encryption of the connection string.
Use encryption sparingly and judiciously though - there is a performance hit.
Edit: Changed the link, Linked to MSDN (more info)
Thanks
Related
I got the connection details of a SFTP server, connected to it with FileZilla, and then successfully downloaded a file from that SFTP.
The only details I had was host, port, user and pass.
Now I'm trying to connect to this same server trough WinSCP .NET assembly (C#)
using(Session session = new WinSCP.Session()) {
session.Open(new SessionOptions() {
Protocol = Protocol.,
HostName = "ftp.*********.be",
UserName ="*****",
Password ="*****"
});
TransferOptions transferOptions = new TransferOptions();
transferOptions.TransferMode = WinSCP.TransferMode.Binary;
TransferOperationResult transferResult;
transferResult = session.GetFiles("/downld/fileonserver.dbf",#"c:\testfolder\localfilename.dbf", false, transferOptions);
Whatever I try here it keeps asking for a key for SSH, but I don't have that key, I generated a 128 bit RSA key somewhere online and put it in the session options like:
SshHostKeyFingerprint = "ssh-rsa 1024 82:09:12:b4:93:92:3a:61:10:90:61:12:b4:XX:XX:XX"
But this just tells me that key is invalid.
I kind of figured out that I maybe need the public/private SSH key from the server to get this to work but I sadly don't have access to this server.
Since FileZilla can connect to it without me entering any KEYS, why can't my C# program do the same?
I'm not an expert when it comes to security related stuff, so please point me in the right direction. I found this thread but I don't have access to .ssh folder on the FTP server and I don't really get where they are going with this.
You are confusing the SSH server public host key verification with the client public key authentication. These are two completely different things. This first involves the public key of the server, while the latter involves your account public key.
Read about SSH Key Pairs to learn the difference.
FileZilla cannot connect without verifying the server's public host key either. On the first connection it always prompts you to accept the key. Once you do, it optionally caches the key and won't prompt you again, unless the key changes.
You have probably forgotten that you got this prompt before or someone else connected to the server before from your machine.
Any SSH (SFTP) client must do the same. You are losing any security had you not verified your server's host key.
You should get the host key fingerprint from your server administrator.
If you had not, you can see it on WinSCP Server and Protocol information dialog.
For details see WinSCP FAQ Where do I get SSH host key fingerprint to authorize the server?
I solved this by just copying the SSH key returned to my FileZilla client into my C# app. I don't know if this is the right thing to do, but at least it got my solution working now.
It was also an SSH-DSS key 2048 key instead of an SSH-RSA 1024, and that's why messing around with the keys kept failing I guess.
I am using the following code in conjunction with dapper ORM to connect to a database :
using (IDbConnection db = new SqlConnection(ConnectionString()))
{
return db.Query<object>(Sql).ToList();
}
The connection string contains database name and login information. I am wondering if while establishing connection to the database server, if any of that information could be visible to someone else.
If you mean in transit: you can force SQL Server to use encrypted connections - https://technet.microsoft.com/en-us/library/ms189067(v=sql.105).aspx
If you mean in-process - the key parts are removed by default so they won't be trivially available to other code with the SqlConnection instance; this is related to the "Persist Security Info" parameter on SqlConnection's connection-string, which defaults to false. Basically, the .ConnectionString property does not expose the credentials once provided. Note that the string will still have existed in memory at some point, so someone with raw access to the process and memory analysis tools may still be able to obtain it; see https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectionstring(v=vs.110).aspx
However, you could also just use Windows authentication via SSPI - this then just uses the app-domain's executing user identity info to connect. Same link as above, but see the "Integrated Security" connection-string parameter.
On the Local Computer: Yes, it would be possible to get access to the information
Over the Network DB Connections: Depends on DB, SQL Server supports SSL, but if you don't use that then you'd be exposing information in your traffic
This would entirely depend on where the connection is being established from and where the connection is being established to.
If either end is in the hands of someone for example, in a distributed client, then they will be able to get hold of the connection details. Typically however, a connection is established "behind the scenes", something like from a web server to a database. Because a connection established like this is all "server side", the connection string is never visible to the "client" of the application and is therefore generally perceived to be safe - of course it is still at the mercy of the infrastructure! :)
It's worth nothing that if this is something like a thick client running on a domain then using something like Windows credentials is an option and would be as secure as the account.
I need to solve the double hop issue for SharePoint 2010 application page. The ASP (C# code behind) page must connect securely to SQL server instance on another host. The secure store service appears to me to only work for a webpart. This can not be accomplished for the application page. Is there a secure alternative?
Current connection string is similar to:
private const string CONNECT_STR = #"Data Source=10.X.X.X,1433
;Initial Catalog=TestCatalogName ; Integrated Security=false;User
ID=testID;Password=********";
SqlConnection con = new SqlConnection(CONNECT_STR)
This seems like a common problem in SharePoint so I hope there is a corresponding common solution.
Only A webpart can use the secure store service in SharePoint 2010. The solution in place uses a SharePoint application page. I am connecting SQL Server and a viable alternative is to use a certificate for the encrypted connection.
See Enabling Encryption section in Using Encryption Without Validation in the client as in my case and concerned only with encryption over the connection. Both the client and server hosts are trusted.
See Selectively using secure connection to SQL Server. The table provides a good explanation of how to achieve the result of a my client using encrypted connection without impacting the SQL server and other connections to it.
The updated connection string is:
private const string CONNECT_STR = #"Data Source=10.X.X.X,1433 ;Initial Catalog=CM_ReleaseManagement ; Integrated Security=false; TrustServerCertificate=true; Encrypt=true; User ID=testID;Password=********";
See "Encrypting Connections to SQL Server" (insufficient reputation to post link) for instructions on configuring SQL Server per Microsoft when you need to encrypt all communications and higher level of security is required. No PII/PHI data involved.
What connection string should I use if SSMS connects to it using simply machine name, without instance name?
I mean it connects using the following string: PCName
I used to connect using PCName/SQLExpress. I cannot set correct connection string in my app in order to connect app to database on this machine.
How can I check what data source I should use? I've checked in Sql Server configuration that server instance named as SQLEXPRESS.
So I tried data source as:
.\SQLEXPRESS
PCName\SQLEXPRESS
.
I'm trying to connect to a service-based database, located in my app folder. So I'm using the following connection string:
data source=PCName;attachdbfilename=|DataDirectory|\spareparts.mdf;integrated security=true;user instance=true;multipleactiveresultsets=true;App=EntityFramework;
If SSMS connects via PCName then your application should be able to use Data Source=PCName. However it depends on whether your application is on the same machine as SSMS or not. If on a different machine it might not be able to connect for a variety of reasons. We can't speculate what the problem might be if all you do to describe the issue is "It won't connect" - what does that mean? Do you get an error message? If so, what is it? Make sure:
SQL Browser service is started
TCP/IP is enabled
Add Network=DBMSSOCN; to the connection string
You've also tried the IP address in addition to PCName
Firewall isn't blocking the SQL Server port
I need to encrypt the data that will be sent/received, client <> server and vice-versa.
Since I can't use SSLStream right now, I am looking for other alternatives.
While thinking about the alternatives I have, I got stucked on how would I send the data to the client in a way it can't be read/intercepted.
Here is how I thinked of doing it:
Client/Server will have a RSA private key inside the application that will be loaded from a string to encrypt/decrypt the data received from the server.
After the initial connection request, the server will send a session id along with a inner AES key/iv.
From here on the client will communicate using both, the RSA and the AES.
I would like to hear from experienced people some new ideas or better ways to do what I need here which is:
Send encrypted data from client to server and vice-versa without using SSLStream and yet having a good level of security.
I understand that having the private key on the client is risk but I am yet to find a better solution.
If you really can't use SSL, you can build poor man's SSL yourself:
The client knows a RSA public key, the server knows the corresponding private key.
To communicate the client creates a random session key that can be used with AES. It encrypts it with the RSA public key, and sends it to the server. It encrypts the rest of the communication with the AES session key.
The server decrypts the first message with the RSA private key, and thus gets the session key. It uses this key for the rest of the communication.
That way the client doesn't contain anything secret, but the communication itself is private. The main thing that's lacking with this scheme is client authentication.
You should also use different nonces/IVs for the server->client and the client->server stream. You might also want to add integrity checking(MACs).
The only way you can do this is using a shared secret: something both the client and the server know, but no-one else does.
Public key SSL works on the premise that a certificate (and hence a key-pair) is locked to a particular server/domain which can be independently confirmed via a third party (the signing authority).
As soon as you get rid of this premise, you are open to man-in-the-middle attacks with public key encryption because you cannot guarantee who you are talking to (or at least you cannot guarantee someone is not intercepting/relaying your messages).
If you use a shared secret, you don't need public keys, certificates or anything else - but if any unauthorised party discovers your secret, you're screwed.
A possible approach:
-Server has a well-known public key and a private key no one knows (not even the clients)
-Client generates a 'handshake' packet and encrypts it with the server's public key. The handshake packet contains any initialisation/authentication stuff you need, plus a randomly generated passphrase + IV to use for AES encryption.
-Server decrypts handshake packet using its private key and now has access to the AES passphrase + IV. It responds with an 'ACK' packet indicating its ready.
-Now client can send data using the AES passphrase to encrypt symmetrically, and the server can decrypt, and vice versa.
There's no need for the client having any private key bundled with it. RSA is specifically designed for data exchange without the need for a shared key.