Snippets

LIQUID Barcodes SHOP API - Payment provider offer token decryption

Updated by Dzmitry Zubialevich

File shop-offertoken-decryption.cs Modified

  • Ignore whitespace
  • Hide word diff
     */
 	
 	var modelJson = PgpDecrypt(/* incoming offer token */, /* your private PGP key */, /* your secret PGP phrase */);
-    var model = ServiceStack.Text.JsonSerializer.DeserializeFromString<OfferToken>(modelJson);
+	var model = ServiceStack.Text.JsonSerializer.DeserializeFromString<OfferToken>(modelJson);
     
     // proceed with payment for model...
 }
 	public decimal RetailPrice { get; set; }
 	public string Currency { get; set; }
 	public string Type { get; set; }
-    public string Description { get; set; }
+	public string Description { get; set; }
 }
Updated by Dzmitry Zubialevich

File shop-offertoken-decryption.cs Modified

  • Ignore whitespace
  • Hide word diff
     /*
      * Decryption demonstration
     */
-	bool isPgp = true;
-	string modelJson;
-	
-	if(isPgp){
-		// if you're using PGP key:
-		modelJson = PgpDecrypt(/* incoming offer token */, /* your private PGP key */, /* your secret PGP phrase */);
-	}
-	else{
-		// for all other keys:
-		// for the payment provider
-		var parts = keyDataCompositeParse(/* incoming offer token */); // we now have two parts: the encrypted-composite-symmetric-key, and the encrypted data
-		modelJson = symmetricDecrypt(asymmetricDecrypt(/* your private key */, parts[0]), parts[1]);
-	}
 	
+	var modelJson = PgpDecrypt(/* incoming offer token */, /* your private PGP key */, /* your secret PGP phrase */);
     var model = ServiceStack.Text.JsonSerializer.DeserializeFromString<OfferToken>(modelJson);
     
     // proceed with payment for model...
 }
 
-string[] keyDataCompositeParse(string compositeKeyData)
-{
-	var tokens = compositeKeyData.Split('|');
-	return new [] { tokens[0], tokens[1] }; // key, data
-}
-
-string symmetricDecrypt(string compositeKey, string encryptedData)
-{
-	var keyParts = symmetricKeyParse(compositeKey);
-	using (var resultBuffer = new MemoryStream(Convert.FromBase64String(encryptedData)))
-	using (var decStream = new CryptoStream(resultBuffer, new RijndaelManaged().CreateDecryptor(keyParts[0], keyParts[1]), CryptoStreamMode.Read))
-	{
-		return new StreamReader(decStream).ReadToEnd();
-	}
-}
-
-string asymmetricDecrypt(string privateKey, string encryptedBase64String)
-{
-	var encryptedBytes = Convert.FromBase64String(encryptedBase64String);
-	
-    CspParameters cspParams = new CspParameters { ProviderType = 1 };
-    RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(cspParams);
-
-    rsaProvider.ImportCspBlob(Convert.FromBase64String(privateKey));
-
-    byte[] plainBytes = rsaProvider.Decrypt(encryptedBytes, false);
-    string plainText = Encoding.UTF8.GetString(plainBytes, 0, plainBytes.Length);
-    return plainText;
-}
-
-class OfferToken
-{
-	public DateTimeOffset Expiration { get; set; }
-	public Item Item { get; set; }
-	public string InternalOfferToken { get; set; }
-}
-
-class Item
-{
-	public long ShopOfferId { get; set; }
-	public decimal RetailPrice { get; set; }
-	public string Currency { get; set; }
-	public string Type { get; set; }
-    public string Description { get; set; }
-}
-
 string PgpDecrypt(string base64Str, string privateKey, string password)
 {
 	var encryptedBytes = Convert.FromBase64String(base64Str);
 	var decoded = new MemoryStream();
 
 	using (var stream = new MemoryStream())
-		using (var writer = new StreamWriter(stream))
+	using (var writer = new StreamWriter(stream))
 	{
 		writer.Write(str);
 		writer.Flush();
 		}
 	}
 	throw new ArgumentException("Can't find signing key in key ring.");
+}
+
+class OfferToken
+{
+	public DateTimeOffset Expiration { get; set; }
+	public Item Item { get; set; }
+	public string InternalOfferToken { get; set; }
+}
+
+class Item
+{
+	public long ShopOfferId { get; set; }
+	public decimal RetailPrice { get; set; }
+	public string Currency { get; set; }
+	public string Type { get; set; }
+    public string Description { get; set; }
 }
Updated by Dzmitry Zubialevich

File shop-offertoken-decryption.cs Modified

  • Ignore whitespace
  • Hide word diff
+using Org.BouncyCastle.Bcpg.OpenPgp;
+using Org.BouncyCastle.Utilities.IO;
+
 void Main()
 {
     /*
      * Decryption demonstration
     */
-
-    // for the payment provider
-    var parts = keyDataCompositeParse(/* incoming offer token */); // we now have two parts: the encrypted-composite-symmetric-key, and the encrypted data
-    var modelJson = symmetricDecrypt(asymmetricDecrypt(/* your private key */, parts[0]), parts[1]);
+	bool isPgp = true;
+	string modelJson;
+	
+	if(isPgp){
+		// if you're using PGP key:
+		modelJson = PgpDecrypt(/* incoming offer token */, /* your private PGP key */, /* your secret PGP phrase */);
+	}
+	else{
+		// for all other keys:
+		// for the payment provider
+		var parts = keyDataCompositeParse(/* incoming offer token */); // we now have two parts: the encrypted-composite-symmetric-key, and the encrypted data
+		modelJson = symmetricDecrypt(asymmetricDecrypt(/* your private key */, parts[0]), parts[1]);
+	}
+	
     var model = ServiceStack.Text.JsonSerializer.DeserializeFromString<OfferToken>(modelJson);
     
     // proceed with payment for model...
 	public string Currency { get; set; }
 	public string Type { get; set; }
     public string Description { get; set; }
+}
+
+string PgpDecrypt(string base64Str, string privateKey, string password)
+{
+	var encryptedBytes = Convert.FromBase64String(base64Str);
+	var str = Encoding.UTF8.GetString(encryptedBytes);
+	var decoded = new MemoryStream();
+
+	using (var stream = new MemoryStream())
+		using (var writer = new StreamWriter(stream))
+	{
+		writer.Write(str);
+		writer.Flush();
+		stream.Seek(0, SeekOrigin.Begin);
+		var input = PgpUtilities.GetDecoderStream(stream);
+
+		try
+		{
+			var pgpObjF = new PgpObjectFactory(input);
+			PgpEncryptedDataList enc;
+			var obj = pgpObjF.NextPgpObject();
+			if (obj is PgpEncryptedDataList)
+			{
+				enc = (PgpEncryptedDataList) obj;
+			}
+			else
+			{
+				enc = (PgpEncryptedDataList) pgpObjF.NextPgpObject();
+			}
+
+			var pbe = enc
+				.GetEncryptedDataObjects()
+				.Cast<PgpPublicKeyEncryptedData>()
+				.FirstOrDefault();
+
+			if (pbe == null)
+			{
+				return string.Empty;
+			}
+
+			var privKey = ReadPrivateKey(privateKey, password, pbe.KeyId);
+
+			if (privKey == null)
+			{
+				return string.Empty;
+			}
+
+			var clear = pbe.GetDataStream(privKey);
+
+			var plainFact = new PgpObjectFactory(clear);
+			var message = plainFact.NextPgpObject();
+
+			if (message is PgpCompressedData)
+			{
+				var cData = (PgpCompressedData)message;
+				var pgpFact = new PgpObjectFactory(cData.GetDataStream());
+				message = pgpFact.NextPgpObject();
+
+				var literalData = (PgpLiteralData)message;
+				var unc = literalData.GetInputStream();
+				Streams.PipeAll(unc, decoded);
+
+				unc.Flush();
+			}
+
+
+			if (pbe.IsIntegrityProtected())
+			{
+				if (!pbe.Verify())
+				{
+					throw new Exception("Message failed integrity check.");
+				}
+			}
+
+			decoded.Position = 0;
+			var result = StreamToString(decoded);
+
+			decoded.Flush();
+			input.Flush();
+			clear.Flush();
+			return result;
+		}
+		catch (Exception e)
+		{
+			throw new Exception(e.Message);
+		}
+	}
+}
+
+string StreamToString(Stream stream)
+{
+	using (var reader = new StreamReader(stream, Encoding.UTF8))
+	{
+		return reader.ReadToEnd();
+	}
+}
+
+PgpPrivateKey ReadPrivateKey(string privateKeyStr, string passPhrase, long keyId)
+{
+	var secreKey = ReadSecretKey(privateKeyStr, keyId);
+	var privateKey = secreKey.ExtractPrivateKey(passPhrase.ToCharArray());
+	if (privateKey != null)
+	{
+		return privateKey;
+	}
+	throw new ArgumentException("No private key found in secret key.");
+}
+
+PgpSecretKey ReadSecretKey(string privateKey, long keyId)
+{
+	using (var stream = new MemoryStream())
+	using (var writer = new StreamWriter(stream))
+	{
+		writer.Write(privateKey);
+		writer.Flush();
+		stream.Position = 0;
+
+		using (var inputStream = PgpUtilities.GetDecoderStream(stream))
+		{
+			var secretKeyRingBundle = new PgpSecretKeyRingBundle(inputStream);
+			var foundKey = secretKeyRingBundle.GetSecretKey(keyId);
+			if (foundKey != null)
+				return foundKey;
+		}
+	}
+	throw new ArgumentException("Can't find signing key in key ring.");
 }
Created by Magnus Olstad Hansen

File shop-offertoken-decryption.cs Added

  • Ignore whitespace
  • Hide word diff
+void Main()
+{
+    /*
+     * Decryption demonstration
+    */
+
+    // for the payment provider
+    var parts = keyDataCompositeParse(/* incoming offer token */); // we now have two parts: the encrypted-composite-symmetric-key, and the encrypted data
+    var modelJson = symmetricDecrypt(asymmetricDecrypt(/* your private key */, parts[0]), parts[1]);
+    var model = ServiceStack.Text.JsonSerializer.DeserializeFromString<OfferToken>(modelJson);
+    
+    // proceed with payment for model...
+}
+
+string[] keyDataCompositeParse(string compositeKeyData)
+{
+	var tokens = compositeKeyData.Split('|');
+	return new [] { tokens[0], tokens[1] }; // key, data
+}
+
+string symmetricDecrypt(string compositeKey, string encryptedData)
+{
+	var keyParts = symmetricKeyParse(compositeKey);
+	using (var resultBuffer = new MemoryStream(Convert.FromBase64String(encryptedData)))
+	using (var decStream = new CryptoStream(resultBuffer, new RijndaelManaged().CreateDecryptor(keyParts[0], keyParts[1]), CryptoStreamMode.Read))
+	{
+		return new StreamReader(decStream).ReadToEnd();
+	}
+}
+
+string asymmetricDecrypt(string privateKey, string encryptedBase64String)
+{
+	var encryptedBytes = Convert.FromBase64String(encryptedBase64String);
+	
+    CspParameters cspParams = new CspParameters { ProviderType = 1 };
+    RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(cspParams);
+
+    rsaProvider.ImportCspBlob(Convert.FromBase64String(privateKey));
+
+    byte[] plainBytes = rsaProvider.Decrypt(encryptedBytes, false);
+    string plainText = Encoding.UTF8.GetString(plainBytes, 0, plainBytes.Length);
+    return plainText;
+}
+
+class OfferToken
+{
+	public DateTimeOffset Expiration { get; set; }
+	public Item Item { get; set; }
+	public string InternalOfferToken { get; set; }
+}
+
+class Item
+{
+	public long ShopOfferId { get; set; }
+	public decimal RetailPrice { get; set; }
+	public string Currency { get; set; }
+	public string Type { get; set; }
+    public string Description { get; set; }
+}
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.