SignedData giving Invalid algorithm specified.exception - c#

I tried to sign and valid my signed data using myCert.pfx file private and public key. But while signing the data I am getting " Invalid algorithm specified." exception
.Net framework we are using is 4.5 and the code is as below
public static void CallMainMethod()
{
string str = "Sign and verify the data";
X509Certificate2 certificate = LoadPrivateKey();
byte[] hashBytes = GetDataHash(str);
byte[] signature = GetDigitalSignature(hashBytes);
}
private static X509Certificate2 LoadPrivateKey()
{
return new X509Certificate2(#"d:\Keys\myCert.pfx", "Pass##123");
}
private static byte[] GetDataHash(string sampleData)
{
//choose any hash algorithm
SHA256Managed managedHash = new SHA256Managed();
return managedHash.ComputeHash(Encoding.Unicode.GetBytes(sampleData));
}
private static byte[] GetDigitalSignature(byte[] data)
{
X509Certificate2 certificate = LoadPrivateKey();
RSACryptoServiceProvider provider = (RSACryptoServiceProvider)certificate.PrivateKey;
return provider.SignHash(data, "SHA256");
}

I believe that legacy RSACryptoServiceProvider doesn't support SHA2 algorithms. Rewrite last method as follows:
private static byte[] GetDigitalSignature(byte[] data)
{
X509Certificate2 certificate = LoadPrivateKey();
RSA provider = certificate.GetRSAPrivateKey();
return provider.SignHash(data, "SHA256", RSASignaturePadding.Pkcs1);
}
This style is preferred as of .NET Framework 4.6 and above (#bartonjs, please correct me if I'm wrong in regards to .NET version).

While #Crypt32 gave the best answer (upgrade to .NET Framework 4.6 or better and use GetRSAPrivateKey() and the better version of SignData -- it's been out over 4 years at this point), if you really need to stay on net45, your easiest answer is to open the PFX with X509KeyStorageFlags.Exportable and copy the key into a better provider.
return new X509Certificate2(#"d:\Keys\myCert.pfx", "Pass##123", X509KeyStorageFlags.Exportable);
...
RSA legacyProv = (RSA)certificate.PrivateKey;
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
provider.ImportParameters(legacyProv.ExportParameters(true));
return provider.SignHash(data, "SHA256");

Related

C# - Generate X509 Certificate based on a given issuer certificate in byte[]

I want to create iothub device certificates from C# code. The root CA is stored in keyvault as a .pfx, fetched as a string, and then converted from base 64 in order to obtain the certificate bytes as it is required for a certificate stored in keyvault: Azure Key Vault Certificates does not have the Private Key when retrieved via IKeyVaultClient.GetCertificateAsync
I want to write a function that will take these bytes, along with a subject name (for the leaf certificate) and will create a x509 certificate (with both public and private keys) that would have the issuer as the root.
Here is what I have sketched so far:
public static X509Certificate2 GenerateCertificateBasedOnIssuer(string subjectName, byte[] issuerByteCert)
{
var issuerCertificate = new X509Certificate2(issuerByteCert);
RSA keyProvider = issuerCertificate.GetRSAPrivateKey();
CertificateRequest certificateRequest = new CertificateRequest($"CN={subjectName}", keyProvider, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
SecureRandom random = new SecureRandom(randomGenerator);
BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
var publicOnlyDeviceCertificate = certificateRequest.Create(issuerCertificate, issuerCertificate.NotBefore, issuerCertificate.NotAfter, serialNumber.ToByteArray());
return publicOnlyDeviceCertificate; // oh no ! :(
}
The issue I am having with this solution is that the created certificate only contains a public key.
I found another solution that appears to solve my problem on another Stack Overflow question using BouncyCastle's X509V3CertificateGenerator: Generate a self-signed certificate on the fly
The issue I have with this solution is that I cannot convert my rootCA certificate's private key to an AsymmetricKeyParameter (first parameter of the X509V3CertificateGenerator.Generate method). I tried converting the issuer's key to AsymmetricKeyParameter using this solution: convert PEM encoded RSA public key to AsymmetricKeyParameter, but I got an invalid operation exception.
I was wondering if I was on the right path (as far as understanding goes) and if there is a way to generate a certificate with a private (and public key) based on the code I currently have in place.
UPDATE: I have been able to convert a private key to an AsymmetricKeyParameter by hardcoding the key as follows:
string testKey = #"-----BEGIN PRIVATE KEY-----
<THE KEY>
-----END PRIVATE KEY-----
";
var stringReader = new StringReader(testKey);
var pemReader = new PemReader(stringReader);
var pemObject = pemReader.ReadObject();
var keyParam = ((AsymmetricKeyParameter)pemObject);
Azure keyvault stores certificate in a pfx format. I am thinking of storing the private key as a secret string. I will keep testing with an hardcoded key for now until I get to a working solution.
I am now testing with BouncyCastle and will come back with a working solution if it works!
The key you pass to CertificateRequest is used as the public key in the cert... so you want to pass a new key, not the issuer's key.
Then, once you now have the subject key, you use CopyWithPrivateKey at the end to glue them back together.
public static X509Certificate2 GenerateCertificateBasedOnIssuer(string subjectName, byte[] issuerByteCert)
{
using (var issuerCertificate = new X509Certificate2(issuerByteCert))
using (RSA subjectKey = RSA.Create(2048))
{
CertificateRequest certificateRequest = new CertificateRequest($"CN={subjectName}", subjectKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
SecureRandom random = new SecureRandom(randomGenerator);
BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
var publicOnlyDeviceCertificate = certificateRequest.Create(issuerCertificate, issuerCertificate.NotBefore, issuerCertificate.NotAfter, serialNumber.ToByteArray());
using (publicOnlyDeviceCertificate)
{
return publicOnlyDeviceCertificate.CopyWithPrivateKey(subjectKey);
}
}

Combining Public Certificate with Private RSA Key in C#

I received from a client public certificate and private RSA key, as follows (only partially displayed here):
-----BEGIN CERTIFICATE-----
MIIFKDCCAxACAQEwDQYJKoZIhvcNAQELBQAwbjELMAkGA1UEBhMCVVMxETAPBgNV
BAgMCElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRMwEQYDVQQKDApDbG91ZFF1
YW50MSUwIwYJKoZIhvcNAQkBFhZjcWFpb3BzQGNsb3VkcXVhbnQuY29tMB4XDTIw
MDkyMzIwMTgyN1oXDTQwMDkxODIwMTgyN1owRjELMAkGA1UEBhMCVVMxETAPBgNV
iESEKmYvylUwce7TcOuVnLtufyXxr8egu43jPvWDHsK0QvhMbx0q2KvyxGneQJ5E
...........
U0oIrq7M0qZTAf1BXEw9wgfQlIKfLzWDbIYKIg==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIIJKQIBAAKCAgEAuxHk8lBZaqRTzhi/jvlj59pehTkK/u2fVHLuHWZPGOvPiAjq
HqrAgM1urPpmQPC2QuWObmhvQ1uluo/tq6V56WZNUEYALZnXhGvVNrvnYfoFooI0
F+1dJI2xQ8AC11Khinj+yAPtKymMhZFOHzQaFnGvjhKWTn/I0MaoJc+TQ8JKbDQ0
ycvopM2finujmIb62cxxhkhkEC5T+yMUJ8MbCnfmWpYux/oU2CXSHrnPympCbx7x
cReH0BeZEZPMI7+1Yi7U+XKGc7RP+zt9AoIBAQDE0BZb3WfertNqmyj9TF73VAwq
SDtSa6MTC8bOdtQewCz9/zC13MSI+jZGRDKSh7nxNL+bgM0OgmM6n/5B/61SIRjM
hswgOU9AHewIFSB/5C/ZcxWqM+PrgYXXYfOl9ZeWs1x+YRKuqk/CW/Z2rHJXykNx
.............
czG95J+2TWdGAjPuFLA596PRXT5KN2ITOWXUym3UksHmonbJ9om+k0ckPr4J
-----END RSA PRIVATE KEY-----
Initially, I scanned many postings here and realized that the easiest way to combine the puplic PEM certificate with private RSA key (PEM format) is by using .NET 5:
// Needs .NET 5, that is .NET Core and VS2019 16.8 or higher
X509Certificate2 X509Cert = X509Certificate2.CreateFromPemFile("cert.cer", "cert.key");
X509Certificate2 cert = new X509Certificate2(mX509Cert.Export(X509ContentType.Pfx, "12345678"), "12345678");
This worked great.
However, later on I realized that the type of project I am targeting (VSTO Excel Add-In) is not supporting .NET 5 yet...
Therefore, I changed the above code to the following, (which also worked) not realizing that it also requires .NET 5...
X509Certificate2 pubOnly = new X509Certificate2("cert.cer");
RSA rsa = RSA.Create();
rsa.ImportRSAPrivateKey(keyBuffer, out _);
X509Certificate2 pubPrivEphemeral = pubOnly.CopyWithPrivateKey(rsa);
X509Certificate2 cert = new X509Certificate2(pubPrivEphemeral.Export(X509ContentType.Pfx, "12345678"), "12345678");
Then when I finally switched to .NET 4.7.2 and now 4.8 I was looking for compatible way to do the same, and tired several methods offered here, but in vain, none did not work - they had complex routines that threw exceptions...
So I am trying now BouncyCastle that helped a lot in the past and came up with this code:
string cerFilePath = Path.Combine(InstallDir, "cert.cer");
X509Certificate2 dotnetCertificate2 = new X509Certificate2(cerFilePath);
string keyFilePath = Path.Combine(InstallDir, "cert.key");
var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(File.OpenText(keyFilePath));
var pemObject = pemReader.ReadObject();
var rsa = DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)pemObject);
Unfortunately, the last line throws exception - there is something incompatible here and I do not know what it is... The exception message states:
"Unable to cast object of type 'Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair' to type 'Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters'."
So if anyone can either correct me with the above BouncyCastle code or show me pure .NET 4.6 - 4.8 code - I'd really appreciate.
EDIT:
So I did find another code from here
private X509Certificate2 CreateCertWithKey()
{
using (Log.VerboseCall())
{
X509Certificate2 x509Cert = null;
try
{
string cerFilePath = Path.Combine(InstallDir, "cert.cer");
using (TextReader tr = new StreamReader(cerFilePath))
{
publicPemCert = tr.ReadToEnd();
}
string keyFilePath = Path.Combine(InstallDir, "cert.key");
using (TextReader tr = new StreamReader(keyFilePath))
{
privatePemKey = tr.ReadToEnd();
}
var keyPair = (AsymmetricCipherKeyPair)new PemReader(new StringReader(privatePemKey)).ReadObject();
var cert = (Org.BouncyCastle.X509.X509Certificate)new PemReader(new StringReader(publicPemCert)).ReadObject();
var builder = new Pkcs12StoreBuilder();
builder.SetUseDerEncoding(true);
var store = builder.Build();
var certEntry = new X509CertificateEntry(cert);
store.SetCertificateEntry("", certEntry);
store.SetKeyEntry("", new AsymmetricKeyEntry(keyPair.Private), new[] { certEntry });
byte[] data;
using (var ms = new MemoryStream())
{
//store.Save(ms, Array.Empty<char>(), new SecureRandom());
data = ms.ToArray();
x509Cert = new X509Certificate2(data);
}
}
catch(Exception ex)
{
Log.Verbose(ex);
}
return x509Cert;
}
}
It runs without problem but with the generated certificate my HttpWebRequest does not work, claiming that TSL/SSL connection cannot be created (and I tries 1.1, 1.2, and 1.3, although I recall that just Tls negotiates the version by itself...
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
The .NET 5 code ran without a problem with exactly the same code for HttpWebRequest...
Just came across this while working through similar issues and I found a way to create the X509Certificate2 object that includes the private key (which I use for XML Signing). It requires that you create a PFX record using the public/private keys, I used OpenSSL:
openssl pkcs12 -export -inkey private-key.pem -in cert.pem -out cert.pfx
You can either open just instantiate the instance directly with the file name:
var cert = new X509Certificate2(filePath);
Or if you have already opened the file somewhere and stored it in base64 format, you can use the bytes:
var bytes = Convert.FromBase64String(pfx_base64);
var cert = new X509Certificate2(bytes);
A lot of credit for this goes to reading Scott Brady's blog.

How to get private key as Byte[] of a password protected pfx fetched from azure key vault

I am fetching my certificate from Azure Key Vault using GetSecretAsync() method and then I am expecting to get the byte[] of the private key and the certificate eventually.
I have my application in .netcore3.1
This is how my code looks like :
var certWithPrivateKey = Client.GetSecretAsync(ConfigurationSettings.AppSettings["AKVEndpoint"], ConfigurationSettings.AppSettings["CertName"]).GetAwaiter().GetResult();
var privateKeyBytes = Convert.FromBase64String(certWithPrivateKey.Value);
X509Certificate2 x509Certificate = new X509Certificate2(privateKeyBytes);
var privateKey = x509Certificate.GetRSAPrivateKey() as RSA;
I get a valid privateKey of type RSACng, but any operation (tried ExportRSAPrivateKey()) on that throws an error of "'privateKey.ExportRSAPrivateKey()' threw an exception of type 'Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException'" and "The requested operation is not supported."
I am not sure how to proceed next here to get the byte[] of the private key and certificate.
Since you do actually seem to need to export: Your current code doesn't load the private key as exportable, so it can't be exported. The fix is to assert exportability:
X509Certificate2 x509Certificate =
new X509Certificate2(privateKeyBytes, "", X509KeyStorageFlags.Exportable);
If that's not enough, then you're encountering the difference between CAPI exportability and CNG exportability (Windows older, and newer, crypto libraries). If the private key from a PFX/PKCS#12 gets loaded into CNG it's only "encrypted exportable", but ExportParameters is plaintext-export.
There's a workaround, though... export it encrypted, then import that somewhere else with a more flexible export policy, then export again.
This snippet uses the .NET Core 3.0+ ExportPkcs8PrivateKey() method, since that's the format you want your data in, and new .NET 5 PemEncoding class to simplify turning the DER encoded output into PEM+DER output. If your exporter is on .NET Framework, this is a more complex problem. For .NET Standard 2.0 there's not really a clean solution (reflect call the methods for .NET Core/.NET 5, otherwise use the Windows-specific version for .NET Framework?).
byte[] pkcs8PrivateKey;
using (RSA privateKey = x509Certificate.GetRSAPrivateKey())
{
pkcs8PrivateKey = ExportPrivateKey(privateKey);
}
File.WriteAllText(
"tls.cer",
new string(PemEncoding.Write("CERTIFICATE", x509Certificate.RawData));
File.WriteAllText(
"tls.key",
new string(PemEncoding.Write("PRIVATE KEY", pkcs8PrivateKey));
...
private static byte[] ExportPrivateKey(RSA privateKey)
{
try
{
// If it's plaintext exportable, just do the easy thing.
return privateKey.ExportPkcs8PrivateKey();
}
catch (CryptographicException)
{
}
using (RSA exportRewriter = RSA.Create())
{
// Only one KDF iteration is being used here since it's immediately being
// imported again. Use more if you're actually exporting encrypted keys.
exportRewriter.ImportEncryptedPkcs8PrivateKey(
"password",
privateKey.ExportEncryptedPkcs8PrivateKey(
"password",
new PbeParameters(
PbeEncryptionAlgorithm.Aes128Cbc,
HashAlgorithmName.SHA256,
1)),
out _);
return exportRewriter.ExportPkcs8PrivateKey();
}
}

Casting private key to RSACryptoServiceProvider not working

I have a X509Certificate2 variable and I'm trying to cast the private key of the variable to a RSACryptoServiceProvider
RSACryptoServiceProvider pkey = (RSACryptoServiceProvider)cert.PrivateKey;
However I get this exception.
System.InvalidCastException: 'Unable to cast object of type 'System.Security.Cryptography.RSACng' to type 'System.Security.Cryptography.RSACryptoServiceProvider'.'
It's weird that this happens because other answers in SO suggested the same procedure as mine but I get an exception. Any solutions to this?
So after a few tries and discussions in the comments I came up with the following solution.
RSA rsa = (RSA)cert.PrivateKey;
(cert.PrivateKey as RSACng).Key.SetProperty(
new CngProperty(
"Export Policy",
BitConverter.GetBytes((int)CngExportPolicies.AllowPlaintextExport),
CngPropertyOptions.Persist));
RSAParameters RSAParameters = rsa.ExportParameters(true);
AsymmetricCipherKeyPair keypair = DotNetUtilities.GetRsaKeyPair(RSAParameters);
The problem was that the variable rsa wasn't exportable. To change this I set a new CngProperty for the export policy. Works perfectly now
Just wanted to note that there's also an extension method that can be used:
using System.Security.Cryptography.X509Certificates;
...
//certificate is a X509Certificate2
using (var rsa = certificate.GetRSAPrivateKey())
{
//the var rsa is an RSA object
//...
}
In my case the same problem was happening when trying to convert local store certificate to RSACryptoServiceProvider as below:
RSACryptoServiceProvider encryptProvider =
certificate.PrivateKey as RSACryptoServiceProvider;
Issue fixed by using RSA instead of RSACryptoServiceProvider.
Putting instructions here in case if someone will be curious how to do that )).
To store some certificate into your machine open Visual Studio Developer Command and type following:
makecert -n "CN=JohnDoe" -sr currentuser -ss someCertStore
...where you can specify and values instead of "JohnDoe" and "demoCertStore".
Now you can use the below code to access certificates from the local certificate store:
public class Program
{
static void DumpBytes(string title, byte[] bytes)
{
Console.Write(title);
foreach (byte b in bytes)
{
Console.Write("{0:X} ", b);
}
Console.WriteLine();
}
static void Main(string[] args)
{
// This will convert our input string into bytes and back
var converter = new ASCIIEncoding();
// Get a crypto provider out of the certificate store
// should be wrapped in using for production code
var store = new X509Store("someCertStore", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
// should be wrapped in using for production code
X509Certificate2 certificate = store.Certificates[0];
RSA rsa = (RSA)certificate.PrivateKey;
(certificate.PrivateKey as RSACng)?.Key.SetProperty(
new CngProperty(
"Export Policy",
BitConverter.GetBytes((int)CngExportPolicies.AllowPlaintextExport),
CngPropertyOptions.Persist));
string messageToSign = "This is the message I want to sign";
Console.WriteLine("Message: {0}", messageToSign);
byte[] messageToSignBytes = converter.GetBytes(messageToSign);
// need to calculate a hash for this message - this will go into the
// signature and be used to verify the message
// Create an implementation of the hashing algorithm we are going to us
// should be wrapped in using for production code
DumpBytes("Message to sign in bytes: ", messageToSignBytes);
HashAlgorithm hasher = new SHA1Managed();
// Use the hasher to hash the message
byte[] hash = hasher.ComputeHash(messageToSignBytes);
DumpBytes("Hash for message: ", hash);
// Now sign the hash to create a signature
byte[] signature = rsa.SignHash(hash, HashAlgorithmName.SHA1, RSASignaturePadding.Pss);
DumpBytes("Signature: ", messageToSignBytes);
// Now use the signature to perform a successful validation of the mess
bool validSignature = rsa.VerifyHash(hash: hash,
signature: signature,
hashAlgorithm: HashAlgorithmName.SHA1,
padding: RSASignaturePadding.Pss);
Console.WriteLine("Correct signature validated OK: {0}", validSignature);
// Change one byte of the signature
signature[0] = 99;
// Now try the using the incorrect signature to validate the message
bool invalidSignature = rsa.VerifyHash(hash: hash,
signature: signature,
hashAlgorithm: HashAlgorithmName.SHA1,
padding: RSASignaturePadding.Pss);
Console.WriteLine("Incorrect signature validated OK: {0}", invalidSignature);
Console.ReadKey();
}
You can avoid the code that is setting the export policy altogether by simply creating the certificate with the export policy already being correct. I used the New-SelfSignedCertificate PowerShell utility to create a certificate that was exportable from inception.
PS C:>New-SelfSignedCertificate -CertStoreLocation "Cert:\CurrentUser\" -Subject "CN=JUSTIN" -KeyExportPolicy Exportable
This negates the need for:
(certificate.PrivateKey as RSACng)?.Key.SetProperty(new CngProperty("Export Policy", BitConverter.GetBytes((int)CngExportPolicies.AllowPlaintextExport),CngPropertyOptions.Persist));

Construct RSACryptoServiceProvider from public key (not certificate)

I am working on a project where I need to use a "public key" to encrypt a message using RSA algorithm. I was provided with a certificate and my first thought was to use Public Key from that certificate and after investigation I learned I need to use RSACryptoServiceProvider for encryption.
I have checked msdn and only method I thought I should use is RSACryptoServiceProvider.ImportCspBlob(byte[] keyBlob).
When I tried to use public key exported from certificate I was getting an error that the header data for certificate is invalid.
I know I can cast X509certificate2.PublicKey.Key to RSACryptoServiceProvider but from what I understood from my client is that going forward I will be given only a public key and not the certificate. This key will have to be saved in .xml configuration file.
So to summarize: Is there a way to generate an RSACryptoServiceProvider given only a certificate's public key?
You can try to look at this example: RSA public key encryption in C#
var publicKey = "<RSAKeyValue><Modulus>21wEnTU+mcD2w0Lfo1Gv4rtcSWsQJQTNa6gio05AOkV/Er9w3Y13Ddo5wGtjJ19402S71HUeN0vbKILLJdRSES5MHSdJPSVrOqdrll/vLXxDxWs/U0UT1c8u6k/Ogx9hTtZxYwoeYqdhDblof3E75d9n2F0Zvf6iTb4cI7j6fMs=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
var testData = Encoding.UTF8.GetBytes("testing");
using ( var rsa = new RSACryptoServiceProvider(1024))
{
try
{
// client encrypting data with public key issued by server
//
rsa.FromXmlString(publicKey);
var encryptedData = rsa.Encrypt(testData, true);
var base64Encrypted = Convert.ToBase64String(encryptedData);
}
finally
{
rsa.PersistKeyInCsp = false;
}
}
You are OK and following a good typical pattern. The Sender of the data does not need the private key.
The following may confirm some of the code you already have figured out.
The one line where I set the private key for the receiver/decoder I left out.
I took this from a test case I have in my build deploy stuff.
byte[] certBytAr; // This is the certificate as bianry in a .cer file (no private key in it - public only)
X509Certificate2 cert2 = new X509Certificate2(certBytAr);
string strToEncrypt = "Public To Private Test StackOverFlow PsudeoCode. Surfs Up at Secret Beach.";
byte[] bytArToEncrypt = Encoding.UTF8.GetBytes(strToEncrypt);
RSACryptoServiceProvider rsaEncryptor = (RSACryptoServiceProvider)cert2.PublicKey.Key;
byte[] dataNowEncryptedArray = rsaEncryptor.Encrypt(bytArToEncrypt, true);
// done - you now have encrypted bytes
//
// somewhere elxe ...
// this should decrpyt it - simulate the destination which will decrypt the data with the private key
RSACryptoServiceProvider pk = // how this is set is complicated
// set the private key in the x509 oobject we created way above
cert2.PrivateKey = pk;
RSACryptoServiceProvider rsaDecryptor = (RSACryptoServiceProvider)cert2.PrivateKey;
byte[] dataDecrypted = rsaDecryptor.Decrypt(dataNowEncryptedArray, true);
Console.WriteLine(" encrypt 1 Way Intermediate " + BitConverter.ToString(dataDecrypted));
string strDecodedFinal = Encoding.UTF8.GetString(dataDecrypted);
if (strDecodedFinal == strToEncrypt)
{
}
else
{
Console.WriteLine(" FAILURE OF ENCRYPTION ROUND TRIP IN SIMPLE TEST (Direction: Public to Private). No Surfing For You ");
}

Categories

Resources