Encrypting/Decrypting a file using Public & Private Key Pair with GnuPG

Hi Folks,

Thank you for visiting my blog today…this is post is mainly for Pro developers. Encryption is crucial to maintain the confidentiality in this digital age for the security of our sensitive information. So here is a blog about it. This is in continuation to my previous blog post on encrypting files using GnuPG.

In this blog post, I will give you sample how you can encrypt/decrypt using GnuPG with command line scripts from C# code.

If you didn’t go through my previous article, I strongly recommend you go through that article below first to understand the background.

Next, in order to encrypt/decrypt a given csv file (taken for simplicity), we can use the following C# codes. For illustration purpose, I have just provided you the logic in the form of a Console.

Encryption:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace eHintsBatchDecryptionTest
{
class Program
{
static void Main(string[] args)
{
string gpgPath = @"D:\Softwares\Kleo Patra\GnuPG\bin\gpg.exe"; //This is the place where you have installed GnuPG Software
string inputFile = "location of input file";
string outputFile = "location of output file";
string passphrase = "passPhrase";
DecryptGPGFile(gpgPath, inputFile, outputFile, passphrase);
}
static void DecryptGPGFile(string gpgPath, string inputFile, string outputFile, string passphrase)
{
using (Process process = new Process())
{
process.StartInfo.FileName = gpgPath;
process.StartInfo.Arguments = $"–batch –yes –pinentry-mode=loopback –passphrase {passphrase} -d -o \"{outputFile}\" \"{inputFile}\"";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
if (process.ExitCode == 0)
{
Console.WriteLine("Decryption successful.");
}
else
{
Console.WriteLine("Decryption failed. Error: " + error);
}
}
}
}
}

Decryption:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace BatchDecryptionTest
{
class Program
{
static void Main(string[] args)
{
string gpgPath = @"D:\Softwares\Kleo patra\GnuPG\bin\gpg.exe";//Once GPG installed, you can look for gpg.exe in the bin folder of the installation
string inputFile = "Input encrypted file";//Replace with your gpg encrypted file location
string outputFile = "Decrypted CSV file"; //give it a name for the decrypted file and location, output file path doesnt exists yet, you may give a sample name
string passphrase = "passPhrase";
DecryptGPGFile(gpgPath, inputFile, outputFile, passphrase);
}
static void DecryptGPGFile(string gpgPath, string inputFile, string outputFile, string passphrase)
{
using (Process process = new Process())
{
process.StartInfo.FileName = gpgPath;
process.StartInfo.Arguments = $"–batch –yes –pinentry-mode=loopback –passphrase {passphrase} -d -o \"{outputFile}\" \"{inputFile}\""; //Pass the PassPhrase, Input and Output file paths as parameters
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
if (process.ExitCode == 0)
{
Console.WriteLine("Decryption successful.");
}
else
{
Console.WriteLine("Decryption failed. Error: " + error);
}
}
}
}
}

All you need is to copy and replace the file locations in the code. Sit back and enjoy encrypting and decrypting with GnuPG. I should say once known, this is the easiest way to encrypt/decrypt from C# code, no strings attached.

If you need any other information, please do let me know in comments.

Cheers,

PMDY

When to use NO-LOCK in SQL – Quick Review

Hi Folks,

Well this post is not related to Power Platform, but I want to bring it on here to specify the significance of using NOLOCK in Power Platform Implementations using SQL Server.

Recently during our Deployment activity, we had a SSIS job which is writing a lot of data into SQL Server, at the same time, we were trying to read the data from the same table. I received never ending Executing query … message. It is when I had arguments on this, hence I would like to share the significance of NOLOCK.

The default behaviour in SQL Server is for every query to acquire its own shared lock prior to reading data from a given table. This behaviour ensures that you are only reading committed data. However, the NOLOCK table hint allows you to instruct the query optimizer to read a given table without obtaining an exclusive or shared lock. The benefits of querying data using the NOLOCK table hint is that it requires less memory and prevents deadlocks from occurring with any other queries that may be reading similar data. 

In SQL Server, the NOLOCK hint, also known as the READUNCOMMITTED isolation level, allows a SELECT statement to read data from a table without acquiring shared locks on the data. This means it can potentially read uncommitted changes made by other transactions, which can lead to what’s called dirty reads.

Here’s an example:

Let’s say you have a table named Employee with columns EmployeeID and EmployeeName.

CREATE TABLE Employee (
    EmployeeID INT,
    EmployeeName VARCHAR(100)
);

INSERT INTO Employee (EmployeeID, EmployeeName)
VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Charlie');

Now, if two transactions are happening concurrently:

Transaction 1:

BEGIN TRANSACTION
UPDATE Employee
SET EmployeeName = 'David'
WHERE EmployeeID = 1;

Transaction 2:

SELECT EmployeeName
FROM Employee WITH (NOLOCK)
WHERE EmployeeID = 1;

If Transaction 2 uses WITH (NOLOCK) when reading the Employee table, it might read the uncommitted change made by Transaction 1 and retrieve 'David' as the EmployeeName for EmployeeID 1. However, if Transaction 1 rolled back the update, Transaction 2 would have obtained inaccurate or non-existent data, resulting in a dirty read.

Key takeaways about NOLOCK:

  • Pros: Reduces memory use, avoids blocking, speeds up reads.
  • Cons: May read uncommitted or inconsistent data.

Using NOLOCK can be helpful in scenarios where you prioritize reading data speed over strict consistency. So, in my case as I want to just view the data, using NOLOCK is good without locking the query. However, it’s essential to be cautious since it can lead to inconsistent or inaccurate results, especially in critical transactional systems.

Other considerations like potential data inconsistencies, increased chance of reading uncommitted data, and potential performance implications should be weighed before using NOLOCK.

Conclusion:

There are benefits and drawbacks to specifying NOLOCK table hint as a result they should not just be included in every T-SQL script without a clear understanding of what they do. Nevertheless, should a decision be made to use NOLOCK table hint, it is recommended that you include the WITH keyword. Using NOLOCK without WITH Statement is deprecated. Always use a COMMIT keyword at the end of the transaction.

Hope this helps…

Cheers,

PMDY