using System;
using System.Security.Cryptography;
using System.Text;
namespace Encrypted_Prefill_Example
{
internal class Example
{
public static void Main(string[] arg)
{
Console.WriteLine("============================== BUY LINKS ==============================");
string baseUrl = "https://secure.2checkout.com";
string prods = "12345678";
string secretKey = "YOUR_SECRET_KEY";
string merchantCode = "YOUR_MERCHANT_CODE";
string url = baseUrl + "/order/checkout.php?CART=1&CARD=1";
string urlString = "PRODS=" + Uri.EscapeDataString(prods) + "&QTY=1&PRICES" + Uri.EscapeDataString(prods) + "[USD]=5&PLNKID=" + GenerateRandomString().ToUpper();
string buyLink = baseUrl + "/order/checkout.php?PRODS=" + Uri.EscapeDataString(prods) + "&QTY=1&CART=1&CARD=2&SHORT_FORM=1";
string data = "BILL_FNAME=John&BILL_LNAME=Doe&BILL_EMAIL=test@test.com&BILL_COUNTRYCODE=RO&URL=" + Uri.EscapeDataString(buyLink);
Console.WriteLine("################################################################################################################");
Console.WriteLine("################################################### V2 #######################################################");
Console.WriteLine("################################################################################################################");
string cypherMethod = "AES256GCM"; // Adjusted for .NET's naming
int ivLength = 12; // GCM standard IV length
int keyLength = 32; // 256 bits
int tagLength = 16;
byte[] initialKeyingMaterial = Encoding.UTF8.GetBytes(secretKey);
byte[] keyDerivationNonceOrSalt = GenerateRandomBytes(keyLength);
byte[] iv = GenerateRandomBytes(ivLength);
PrintDebugInfo("NONCE", keyDerivationNonceOrSalt);
PrintDebugInfo("IKM, IPN KEY", initialKeyingMaterial);
PrintDebugInfo("IV", iv);
byte[] encryptionKey = new HMACSHA256(keyDerivationNonceOrSalt).ComputeHash(initialKeyingMaterial);
PrintDebugInfo("DERIVED ENCRYPTION KEY", encryptionKey);
byte[] encryptedData, decryptedData, tag;
encryptedData = Encrypt(Encoding.UTF8.GetBytes(data), encryptionKey, iv, out tag, keyDerivationNonceOrSalt);
decryptedData = Decrypt(encryptedData, encryptionKey, iv, tag, keyDerivationNonceOrSalt);
PrintDebugInfo("RESULTING AUTHENTICATION TAG", tag);
PrintDebugInfo("INPUT DATA", Encoding.UTF8.GetBytes(data));
PrintDebugInfo("ENCRYPTED DATA", encryptedData);
PrintDebugInfo("DECRYPTED DATA", decryptedData);
string base64Payload = Convert.ToBase64String(keyDerivationNonceOrSalt)
+ '.' + Convert.ToBase64String(tag)
+ '.' + Convert.ToBase64String(iv)
+ '.' + Convert.ToBase64String(encryptedData);
Console.WriteLine();
Console.WriteLine("DATA PAYLOAD STRUCTURE (BASE64-encoded components): NONCE.TAG.IV.ENCRYPTED_DATA");
Console.WriteLine("DATA PAYLOAD (BASE64): " + base64Payload);
string checkoutUrl = "checkout.php?PRODS=" + Uri.EscapeDataString(prods) + "&QTY=1";
url = baseUrl + "/order/pf.php?V=2&MERCHANT=" + Uri.EscapeDataString(merchantCode) + "&DATA=" + Uri.EscapeDataString(base64Payload) + "&URL=" + Uri.EscapeDataString(checkoutUrl);
Console.WriteLine();
Console.WriteLine(url);
}
private static void PrintDebugInfo(string prefix, byte[] data)
{
Console.WriteLine(prefix + " (" + (data.Length * 8) + " bits): " + BitConverter.ToString(data).Replace("-", ""));
Console.WriteLine();
}
private static string GenerateRandomString(int length = 10)
{
const string characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var randomString = new StringBuilder(length);
Random random = new Random();
for (int i = 0; i < length; i++)
{
randomString.Append(characters[random.Next(characters.Length)]);
}
return randomString.ToString();
}
private static byte[] GenerateRandomBytes(int length)
{
// Create a byte array to hold the random bytes
byte[] randomBytes = new byte[length];
// Generate random bytes using RNGCryptoServiceProvider
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
rng.GetBytes(randomBytes);
}
return randomBytes;
}
private static byte[] Encrypt(byte[] plaintextBytes, byte[] key, byte[] iv, out byte[] tag, byte[] associatedData)
{
byte[] ciphertextBytes = new byte[plaintextBytes.Length];
tag = new byte[16]; // GCM tag length of 128 bits
using (AesGcm aesGcm = new AesGcm(key))
{
aesGcm.Encrypt(iv, plaintextBytes, ciphertextBytes, tag, associatedData);
}
return ciphertextBytes;
}
private static byte[] Decrypt(byte[] ciphertextBytes, byte[] key, byte[] iv, byte[] tag, byte[] associatedData)
{
byte[] plaintextBytes = new byte[ciphertextBytes.Length];
using (AesGcm aesGcm = new AesGcm(key))
{
aesGcm.Decrypt(iv, ciphertextBytes, tag, plaintextBytes, associatedData);
}
return plaintextBytes;
}
}
}