I have the following problem:
I have encrypted a column in my SQL Database by using a Symmetric Key. Now I have the encrypted value in the database and when I open the key and execute the query:
SELECT Convert(varchar, DECRYPTBYKEY(ColumnName)) as ClientSecret
FROM dbo.Sample
In Management Studio query editor it is ok and it returns the decrypted value.
But when I try to execute the same thing as a SqlCommand from my ASP.NET application it returns null.
Code:
string query = "SELECT Convert(varchar, DECRYPTBYKEY(ColumnName)) as ClientSecret FROM dbo.Sample";
var con = ConfigurationManager.ConnectionStrings["connectionName"].ConnectionString;
using (SqlConnection connection = new SqlConnection(con))
{
SqlCommand command = new SqlCommand(query, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
//the value of client secret here is null
var readerTest = reader["ClientSecret"];
}
}
finally
{
// Always call Close when done reading.
reader.Close();
}
}
My questions are the following:
First, why this does not work?
Second, is there a better way to decrypt the value of the column in the application (not by asking the server to do it) by using its encryption algorithm?
The only explanation that makes sense is that you already have the key open in SQL Server Management Studio since DecryptByKey requires the symmetric key to be open prior to decryption. To check which keys are open, execute the sql below just prior to selecting the data.
select * from sys.openkeys
If your intent is to combine opening the key with decrypting the data, then DECRYPTBYKEYAUTOCERT would be a good function to use. If you want to encrypt and decrypt data at the client instead of the server, you should look at SQL Server 2016 Always Encrypted. Be careful how it is configured because using deterministic encryption with a data set having low cardinality could result in the ability for a bad actor to create a hash table to indirectly decrypt the data. Also, generally clients are more prone to attack than servers.
Related
VS Express 2012, SQL Server Express 2012, Win 8.1
Hello,
I have a (very) simple WCF hosted as a web service on IIS. I also have a SQL Server instance (with 1 table) installed on the same machine.
I need a step-by-step guide on how to connect to SQL from the WCF (VB) and retrieve a single record from the table (ie: "SELECT LAST NAME FROM MYTABLE WHERE PK = 1;"). That's it. I don't need a 1,200 page manual -- which is all Google keeps throwing at me.
Anyone know of a quick, clean resource?
Thanks,
Jason
The main classes that are involved are SqlConnection and SqlCommand. The documentation of the classes contains some samples on how to use them. To get you started, here is a small sample:
Dim connStr = "Data Source=SQLServerName\InstanceName;Initial Catalog=DatabaseName;Integrated Security=SSPI"
Using conn As New SqlConnection(connStr)
conn.Open()
Using cmd = conn.CreateCommand()
cmd.CommandText = "SELECT LAST_NAME FROM MYTABLE WHERE PK = #pk"
cmd.Parameters.AddWithValue("#pk", 1)
Dim result = cmd.ExecuteScalar()
If Typeof result Is DbNull Then
' Handle null value
Else
' Otherwise
End If
End Using
End Using
This sample assumes that you want to retrieve a single cell as in your statement. If you want to retrieve tabular data, have a look a the SqlDataReader or SqlDataAdapter class.
Please note that - especially in server applications - it is important to dispose of the created instances properly.
There is no difference on using ADO.NET in a WCF service or in a normal application from the point of view of the classes required.
The first thing needed is a connection string that allows your SqlConnection object to find the host and the database that you want to use. Here examples on connection strings
Then you usually need a SqlCommand that encapsulates the SQL text and parameters needed to retrieve the data (Here you setup your SELECT statement and conditions)
Finally you need a SqlDataReader that get the result of the command execution and allows you to loop over the results.
Here a sample that could get you started.
Keep in mind that this is just a minimal todo-list and there are numerous other ways to work with data. Basic objects like SqlDataAdapter, Dataset, DataTable present different ways to load data from a database and use that data. Then on top of these there are technologies like Linq To Sql and Object Relational Mapper tools that abstract the data access and offer high level functionality on top of data.
That's probably the reason you get so much informations on data access technologies
I see a couple of DataContext connection string questions. I'm going to try to differentiate this one a bit:
How does one construct a generic connection string to a database, localhost | User-PC\User | Some database... (it is hosted/managed by Microsoft SQL 2008)
I notice that it is IDisposable. So if I have multiple users hitting my site, my code can only access the database one instance at a time, and has to wait until each instance is disposed, in order for the data to be consistent for each user?
Is it possible, by any chance, to somehow enable LINQ in F#-Interactive, and connect to the database from there? I cannot figure out how to enable/load the System.Data dll into fsi. Maybe that is unique to my installation, or it is a common thread? (ie, my installation also does not recognize windows.base.dll--I have to manually get it from programs\reference assemblies).
Anyhow, I've pretty much conclusively discovered that
let x = new System.Data.Linq.DataContext("localhost")
...does not work.
1) How does one construct a generic connection string to a database?
There is no generic way to construct a connection string. The best thing to do is to keep the connection string in some configuration file where you can change it depending on your configuration (the name of SQL Server machine, authentication options, whether it is a file-based database or normal). There is a web site with examples for most of the options.
2) I notice that it is IDisposable. So if I have multiple users hitting my site, my code can only access the database one instance at a time [...]?
No, this is not how DataContext works. The DataContext does not keep a live connection to the server that would block anybody else from using the SQL server. It keeps some state (i.e. cached entities that were already obtained) and it uses optimistic concurrency to make sure that the state is consistent (you can use transactions to prevent other connections, if that's what you want).
3) Is it possible, by any chance, to somehow enable LINQ in F#-Interactive [...]?
That shouldn't be a problem. You can reference assemblies using #r "foo.dll" in F# interactive. The typical approach for F# 2.0 is to generate the data context using C# tools and then just reference it (for F# 3.0, things are easier because you can just use type provider).
If you generate LINQ to SQL data context for Northwind in C#, the F# Interactive use would look like this:
#r #"<whatever_path>\Northwind.dll"
#r "System.Data.Linq.dll"
open Northwind
open Microsoft.FSharp.Linq
let connStr = #"Data Source=.\SQLEXPRESS;AttachDbFilename=<path>\NORTHWND.MDF;" +
#"Integrated Security=True;User Instance=True"
let operation () =
// Using 'use' to make sure it gets disposed at the end
use db = new NorthwindDataContext(connStr)
// do something with the database
There actually is a somewhat generic way to construct a connection string:
open System.Data.Common
open System.Data.SqlClient
let providerName = "System.Data.SqlClient"
let factory = DbProviderFactories.GetFactory(providerName)
let cnBuilder = factory.CreateConnectionStringBuilder() :?> SqlConnectionStringBuilder
cnBuilder.DataSource <- "localhost"
cnBuilder.InitialCatalog <- "MyDatabase"
cnBuilder.IntegratedSecurity <- true
let connStr = cnBuilder.ConnectionString
My approach was to have 1 connection string and then use that for all of my DataContext connections. So this code builds the EntityConnectionString based on MyConnString:
protected override MyEntities CreateObjectContext()
{
string ConnString =ConfigurationManager.ConnectionStrings["MyConnString"];
string seConn = ConfigurationManager.ConnectionStrings["MyEntities"].ToString();
EntityConnectionStringBuilder ecsb = new EntityConnectionStringBuilder(seConn);
ecsb.ProviderConnectionString = ConnString;
EntityConnection ec = new EntityConnection(ecsb.ToString());
ScheduleEntities ctx = new ScheduleEntities(ec);
return ctx;
}
I need to get some sensitive data from an Oracle server to a SQL Server for use in my ASP.NET website. Lets say its passwords. Our security guys say that these passwords need to be secured every step of the way. My website needs to be able to compare user input to these passwords. These passwords must be transferred from the Oracle server to SQL Server at night and can only be used on SQL Server during the day.
The best solution I can come up with is that we need to hash the passwords on Oracle and pass the hashes to SQL Server (lets assume the connection between the two is secure, because that's not my job :P ). Then my ASP.NET web application needs to be able to implement the exact same hashing on user input so we can compare the input hash to the database hash.
So my question is: how can I hash something using the same algorithm/key/salt on Oracle and .NET? I know how to use the .NET hashing functions, but I'm not sure what I can use in Oracle that would be comparable... I could potentially pass them in plain text from ASP.NET to SQL Server and hash them there if that's easier, but lets call that "Plan B".
Your datastore should be storing hashed values, on the asp.net side you'll need to implement an md5 function to convert strings to the hash, and then compare against the hashed value in your db.
http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_obtool.htm#i1003449
Oracle does have the ability to use MD5 hash, which you can pass to SQL server and implement, as well as ASP.net.
SQL Server md5
http://www.lazerwire.com/2011/10/ms-sql-md5-hash.html
ASP.net MD5
public string CalculateMD5Hash(string input)
{
// step 1, calculate MD5 hash from input
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
// step 2, convert byte array to hex string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
I've created an application using ASP.NET with Access DB, now I found somee.com who support only SQL Server DBs, so Now I must convert my Access DB to SQL Server DB.
Is there any tool who can do the trick ?
This is some code I'm using in my web application :
Public Shared Function conecter() As OleDbConnection
Dim MyConnexion As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data source=" & System.AppDomain.CurrentDomain.BaseDirectory & "/Learning.mdb")
MyConnexion.Open()
Return MyConnexion
End Function
Public Shared Function lecture(ByVal requete As String) As OleDbDataReader
Dim Mycommand As OleDbCommand = conecter().CreateCommand()
Mycommand.CommandText = requete
Dim myReader As OleDbDataReader = Mycommand.ExecuteReader()
Return myReader
End Function
In this case, If I convert my database I must change the OleDbConnexion and other things or I can just leave them like that ?
Your connection string will need to change. Connectionstrings.com is a good resource for this if you're having problems figuring out how to set up a SQL connection string.
For upward migration, take a look at the Access Upsize Wizard - this link is for 2002 since I'm not sure what access version you have.
If for some reason you do not have sufficient access to your SQL database to handle an upsize directly, you'll likely need to just generate the database schema and knock out a bit of migration code.
If you have access 2007, there is inbuilt option convert access database to SQL other wise there are somany tools available for free.
bullzip free converter
Try MUST
It was developed by a colleague of mine (we designed the website: www.upsizing.co.uk).
It does a fair bit more than the MS tools.
I'm designing a web service in ASP.NET and VS2008, and am using typed datasets for retrieving table data. These work well and establish their own connections through their associated TableAdapter objects. Edit: I'm using VB, BTW!
I am now attempting to run a custom SQL string using a DataAdapter and a Command object, however I need to reference a Connection object in order for the Command to work. What is the best way to handle this? Should I:
a) Create a global connection object using Global.asax, retrieving the connection string from web.config? (I've been trying that one already, with not much success)
b) Create a class-level connection object using the InitialiseComponent method, also retrieving the ConnectionString from web.config?
c) Retrieve a Connection from one of the TableAdapters that I've already created in my typed DataSets?
d) Something else I haven't thought of yet?
BTW I've been finding it very difficult to extract a ConnectionString from web.config, so any help with that would be appreciated also!
I'm not entirely inexperienced with ASP.NET, but my last big project used VS2003, and I want to make sure that I'm using the current tools correctly.
To extract the connection string, use
WebConfigurationManager.ConnectionStrings["name"].ConnectionString
It's best to open and close the connections as close as possible to their use. ADO.NET will do connection pooling so that this won't be expensive:
var connectionString =
WebConfigurationManager.ConnectionStrings["name"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand("query", conn))
{
conn.Open();
// Use the command
}
}
For Connection and data access problems I will advise you to go with some kind of Data Helpers like Microsoft Data Access Application Block
Here you can find small tutorial about how to use it.
For getting connectionstring from web.config use folowing methods
public static string GetConnectionString( string strConstringKey )
{
return ConfigurationManager.ConnectionStrings[strConstringKey];
}
public static bool GetConnectionString(string strConstringKey, ref string strConstring)
{
return (strConstring = ConfigurationManager.ConnectionStrings[strConstringKey] ) == null ? false : true ;
}