mastercard / client-encryption-csharp Goto Github PK
View Code? Open in Web Editor NEWLibrary for Mastercard API compliant payload encryption/decryption.
License: MIT License
Library for Mastercard API compliant payload encryption/decryption.
License: MIT License
Description
When using this plugin in .net framework 4.8 it gives an error.
AES/GCM/NoPadding is unsupported on .NET Standard < 2.1
To Reproduce
JweEncryption.encryptPayload(requestPayload, config);
Expected behavior
encryption should work as this plugin is targeting less than 2.1
the latest version of the lib, with the fix related to the umlaut characters, is not compatible with .net Framework 4.8
Can you move back to .net Standard 2.0 that sill support .net Framework 4.8?
Configuration:
var config = JweConfigBuilder.AJweEncryptionConfig()
//...
.WithEncryptionPath("$", "$")
.Build();
Input:
[
{},
{}
]
Expected output:
{
"encryptedData": "ew0KICAia2lkIjogIjc2M...nrs60sQQQdvYxLPwq9g"
}
Actual output:
Mastercard.Developer.ClientEncryption.Core.Encryption.EncryptionException:
Payload encryption failed! ---> Newtonsoft.Json.JsonReaderException: Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.
Could you add the required configuration for "MDES Customer Services" to the document at https://github.com/Mastercard/client-encryption-csharp/wiki/Service-Configurations-for-Client-Encryption-C%23?
Our project use framework 4.7.1 and we are using C# coding
I try use both MasterCard client encryption “core” DLL downloaded from NuGet
Version 1.3 unfortunately when I reach to the encryption “payload” I got an error that zero padding not supported with version <2.0
Version 2 , when am trying to set the configuration an exception raised directly “netstandard dll version conflict” I try to download this dll with v2.1 but I couldn’t get it😢
how can I solve this problem
Pleas help m
e
Description
A clear and concise description of what is the question, suggestion, or issue and why this is a problem for you.
To Reproduce
Steps to reproduce the behavior.
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Additional context
Add any other context about the problem here (OS, language version, etc..).
Related issues/PRs
Has a similar issue/PR been reported/opened before?
Suggest a fix/enhancement
If you can't fix the bug yourself, perhaps you can point to what might be causing the problem (line of code or commit), or simply make a suggestion.
If this is a Feature request, please check out this.
Configuration:
var config = JweConfigBuilder.AJweEncryptionConfig()
//...
.WithEncryptionPath("$", "$.encryptedDataParent")
.Build();
Input:
{"data": {}}
Expected output:
{
"encryptedDataParent": {
"encryptedData": "ew0KICAia2lkIjogIjc2M...nrs60sQQQdvYxLPwq9g"
}
}
Actual output:
{
"encryptedData": "ew0KICAia2lkIjogIjc2M...nrs60sQQQdvYxLPwq9g"
}
Please verify whether csharp-netcore or csharp has been deprecated. I cannot locate csharp-netcore in the openapi-generator-cli, and the code generated using csharp-generator does not function as expected in your provided example.
Description
I am having an issue when trying to decrypt using the payload encryption library when Java encrypts with a Public Key, C# is not able to decrypt the payload with a Private Key.
Payload Encryption Flows:
• C# encrypt request -> Java decrypt request -> Java encrypt response -> C# decrypt response
This flow fails every time on the C# decrypt response, Java has no issue reading the encrypted request, just when it is sent back, C# seems to not be able to decrypt it
• Java encrypt request -> Java decrypt request -> Java encrypt response -> Java decrypt response
This works every time
• C# encrypt request -> C# decrypt request -> C# encrypt response -> C# decrypt response
This works every time
To Reproduce
Using a self signed PKCS12 public / private key.
-- Java
String data = "{\"Hello\" : \"World\"}";
String encryptedPayload = encryptData(getPublicKey(ks), data);
System.out.println(encryptedPayload); // This is the json payload encrypted from mastercard lib
private static X509Certificate getPublicKey(KeyStore ks) throws KeyStoreException
{
String alias = ks.aliases().nextElement();
X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
return cert;
}
private static String encryptData(X509Certificate cert, String data) throws ParseException, CertificateException, EncryptionException, IOException
{
// Fetch the public Cert from the service, so the payload can be encrypted
JweConfig jweConfig = JweConfigBuilder.aJweEncryptionConfig()
.withEncryptionCertificate( cert )
.withEncryptionPath("$", "$")
.withEncryptedValueFieldName("encryptedValue")
.build();
String encryptedValue = JweEncryption.encryptPayload(data, jweConfig);
return encryptedValue;
}
-- C#
RSA privateKey = LoadDecryptionKey("CertName.pfx", null, payloadEncryptionPassword);
String javaEncryptedData = "{\"encryptedValue\":\"eyJraWQiOiJlYmFiMzgwOWRkZjhjYmYzZmE2YzQwZjk3NjU1ZDg4YThjZGQ0M2JkY2FiZjQxOTc4YTVmNWExOTAzYzFjZDQ0IiwiY3R5IjoiYXBwbGljYXRpb24vanNvbiIsImVuYyI6IkEyNTZHQ00iLCJhbGciOiJSU0EtT0FFUC0yNTYifQ.hchoaYMxp2grF1NcYiGPHgYxzPipjltj0foSFpcg-O4y-mU7gqMcvsyx_7cy4iOxFsYZz16HE5FV4AcwJB8XQAa1TKz_t072isuHfaBeN2MC5ikgCUAg9wdKjCkmpr5l_yU6MOygsm23Zh0_VOgwhHCMWpNddDfxkS1G-_NLmmKAAb-pk46ni6T_uSU4iXYY408Xeww6tl9HJNB1IHUGh-ev5FMakf7Ey1MsswnLDNwzoFmOHivKWOeueYHeqep84UhWKp6oIHwm_Dqb7Q5xVV9KS0_MIx8XYcqKglw52Lw1iEQ7_Agiy_Xdjhoot0X9iSraeH2rfET-rOvMivG5Uw.RFtola7NDnkDdmIBmXKveg.GvyOaL7to-5vB3j4vzk.gh_IIQSOjAWsuH5xH_EP6Q\"}\r\n"; // This would be the payload that Java Producted
String decryptedData = decryptData(privateKey, javaEncryptedData); // Never gets here
public static RSA LoadDecryptionKey(string pkcs12KeyFilePath, string decryptionKeyAlias, string decryptionKeyPassword,
X509KeyStorageFlags keyStorageFlags = X509KeyStorageFlags.DefaultKeySet)
{
if (pkcs12KeyFilePath == null) throw new ArgumentNullException(nameof(pkcs12KeyFilePath));
var certificate = new X509Certificate2(pkcs12KeyFilePath, decryptionKeyPassword, keyStorageFlags);
return certificate.GetRSAPrivateKey();
}
private static String decryptData(RSA privateKey, String data)
{
JweConfig jweConfig = JweConfigBuilder.AJweEncryptionConfig()
.WithDecryptionKey(privateKey)
.WithDecryptionPath("$.encryptedValue", "$").Build();
String decrypted = JweEncryption.DecryptPayload(data, jweConfig); // Error happens here
return decrypted;
}
Expected behavior
To be able to use payload encryption between Java and C#. This currently works when C# sends Java encrypted data, but when Java sends a response back C# can't extract the payload.
Screenshots
If applicable, add screenshots to help explain your problem.
Additional context
Add any other context about the problem here (OS, language version, etc..).
Stack Trace
System.ArgumentException
HResult=0x80070057
Message=The specified nonce is not a valid size for this algorithm. (Parameter 'nonce')
Source=System.Security.Cryptography.Algorithms
StackTrace:
at System.Security.Cryptography.AesGcm.CheckParameters(ReadOnlySpan1 plaintext, ReadOnlySpan
1 ciphertext, ReadOnlySpan1 nonce, ReadOnlySpan
1 tag)
at System.Security.Cryptography.AesGcm.Decrypt(Byte[] nonce, Byte[] ciphertext, Byte[] tag, Byte[] plaintext, Byte[] associatedData)
at Mastercard.Developer.ClientEncryption.Core.Encryption.AES.AesGcm.Decrypt(Byte[] secretKeyBytes, JweObject jweObject) in C:\Git\client-encryption-csharp\Mastercard.Developer.ClientEncryption.Core\Encryption\AES\AesGcm.cs:line 33
at Mastercard.Developer.ClientEncryption.Core.Encryption.JWE.JweObject.Decrypt(JweConfig config) in C:\Git\client-encryption-csharp\Mastercard.Developer.ClientEncryption.Core\Encryption\JWE\JweObject.cs:line 36
at Mastercard.Developer.ClientEncryption.Core.Encryption.JWE.JweEncryption.DecryptPayloadPath(JToken payload, String jsonPathIn, String jsonPathOut, JweConfig config) in C:\Git\client-encryption-csharp\Mastercard.Developer.ClientEncryption.Core\Encryption\JWE\JweEncryption.cs:line 77
at Mastercard.Developer.ClientEncryption.Core.Encryption.JWE.JweEncryption.DecryptPayload(String payload, JweConfig config) in C:\Git\client-encryption-csharp\Mastercard.Developer.ClientEncryption.Core\Encryption\JWE\JweEncryption.cs:line 50
This exception was originally thrown at this call stack:
[External Code]
Mastercard.Developer.ClientEncryption.Core.Encryption.AES.AesGcm.Decrypt(byte[], Mastercard.Developer.ClientEncryption.Core.Encryption.JWE.JweObject) in AesGcm.cs
Mastercard.Developer.ClientEncryption.Core.Encryption.JWE.JweObject.Decrypt(Mastercard.Developer.ClientEncryption.Core.Encryption.JweConfig) in JweObject.cs
Mastercard.Developer.ClientEncryption.Core.Encryption.JWE.JweEncryption.DecryptPayloadPath(Newtonsoft.Json.Linq.JToken, string, string, Mastercard.Developer.ClientEncryption.Core.Encryption.JweConfig) in JweEncryption.cs
Mastercard.Developer.ClientEncryption.Core.Encryption.JWE.JweEncryption.DecryptPayload(string, Mastercard.Developer.ClientEncryption.Core.Encryption.JweConfig) in JweEncryption.cs
Class where the issue is: Mastercard.Developer.ClientEncryption.Core.Encryption.AES.AesGcm
This issue is happens when calling aes.Decrypt specifically. It appears that the Decrypt method is not happy about the size of the nonce byte array which is 16 characters. I was doing some research and thought this should be 12 characters instead or 96 bits according to the NIST, which might explain why Decrypt is not happy with this size.
internal static byte[] Decrypt(byte[] secretKeyBytes, JweObject jweObject)
{
#if NETSTANDARD2_1
byte[] plaintext;
using (var aes = new System.Security.Cryptography.AesGcm(secretKeyBytes))
{
byte[] nonce = Base64Utils.URLDecode(jweObject.Iv);
byte[] aad = Encoding.ASCII.GetBytes(jweObject.RawHeader);
byte[] authTag = Base64Utils.URLDecode(jweObject.AuthTag);
byte[] ciphertext = Base64Utils.URLDecode(jweObject.CipherText);
plaintext = new byte[ciphertext.Length];
aes.Decrypt(nonce, ciphertext, authTag, plaintext, aad);
}
return plaintext;
#else
throw new EncryptionException("AES/GCM/NoPadding is unsupported on .NET Standard < 2.1");
#endif
}
Related issues/PRs
Has a similar issue/PR been reported/opened before?
Suggest a fix/enhancement
If you can't fix the bug yourself, perhaps you can point to what might be causing the problem (line of code or commit), or simply make a suggestion.
If this is a Feature request, please check out this.
Description
German Character not supported due to ASCII encoding
To Reproduce
Encrypt any payload with umlauts characters then the decrypted one is with a question mark in place of umlaut
Hello! @latompa @swaj @jkenn99 @DRuggeri I'm encountering this error, payload is already encrypted.
Error 400 status code
{"Errors":{"Error":[{"Source":"VALIDATION_ERROR","ReasonCode":"ENCRYPTION_ERROR","Description":"-3001","Recoverable":false,"Details":"Request is not encrypted"}]}}
Expected behavior
Should return 200 status code.
Screenshots
Payload encryption
Http request
Additional context
Encrypted payload
{
"path": {
"to": {
"encryptedFoo": {
"encryptedValue": "81316b9d66dccded47c9f9bfdb06a9591304c3cc6be4cd69c9723b5083de4cc00e3a55575a2071cb0fd7db2d2038aad6e2a507175e69e740a66cf312a23d06b467bb2d53ea3ec718bab674eeb9a17ec1df929cdb507d5448477495b6ff2c9aa23f47fab0f36e3ab82ce9c3703d4847335ce6300105b8c9328df52c5c623a149869b5a9f020698cda0fa594bd7848a7fac713699f394237ad346424e1d7c659fa19f8e5d7feaeefd0d4e7681de08a3a5b3462910ae30048ad38bfcdb5996570795d53e9675d1d53f45ebd726432fbc93778045636004bdfb69cdebb8728f4ce1e47bb68163fc81d4c634ad9d6eb04934dd7cdc47b66f1f2fdc03ad7b9c64bcd9e65b9a41e8d2749eb1ba59774cf4688ece71c3687091aed35a6b5f24f574f9e7d07670e56bdfd407c543c8ef563813fe19f2f476b6a4e51be1519eb4098a7f3f9754f2b31fa7e8af7a0f923110f8a0bf0642da8b5ee88f3b0d51c28855e626b70d1e281a7ab47d9aa530f8597df6c9b7432c6205b9b7b3e0f76fc5b112984d7b1c4dbc786bf5813693f82b77c7c025e00cf38fb73e7d635e5c49b632625583b59308479badfc014b3886221f500cd3d0f7f39a0bdc3fe8824453351ebe87161ca6f7fd86619cf8bc8cb541df0d6f4025217747b84ff98d7cb90b4ee3529b72db1",
"iv": "bf5ec87ae3710845f361171b1c2dab94",
"encryptedKey": "6923dd05261923c386ca1b74f00f9ee22009c19ce60e01aaa9c1c1b40203b823fba9aab8159598afdf37e3f740eb4cf89f58e3401013ab45bf7e96101a94eeb77c436b136b05c967deab976de6b936e7c023ed0e67f4703c017664c22fab5c755b0ec1ef509a4814062e86f9bca2e41ff2d369e54e4f5912e3adc44b7d9d99d50565d13dca580625a56a332a8080237993747870b1e10aba3bf1e014487ac6f0b8466f012ac16b04c97e2c79b060e4c60ffc89a0a03788ee023298bc3e84b35480289cf553dd835c0310a43e28f918063786882b3aae78182687fea4610d36692a991c26d29653fd4dda5bfb7eb3e024d5fdb295cd554e470d671c299f53cc7f"
}
}
}
}
cardInfo
is now fundingAccountInfo
The current implementation is relying on the underlying operating system to extract and use keys from X509 certificates.
With the expanding popularity of serverless deployment, it would be nice to have an Operating system-agnostic version.
My advice would be to extend the library and enable encryption / decryption based on public/private keys (not only an X509 certificate) in the FieldLevelEncryptionConfigBuilder.
The user can provide the keys in a custom way, without the need to use operation system services.
When I use EncryptionUtils.LoadDecryptionKey, I don't always have an actual key file (apps run in containers, kube clusters etc).
Add a new LoadDecryptionKey method that can take a byte array. This byte array would be injected by the app's environment/secrets.
no alternatives
Add any other context or screenshots about the feature request here.
Bug Report Checklist
Have you provided a code sample to reproduce the issue?
Have you tested with the latest release to confirm the issue still exists?
Have you searched for related issues/PRs?
What's the actual output vs expected output?
Description
I am having an issue when trying to decrypt using the payload encryption library C# is not able to decrypt the payload with a Private Key. This is with Mastercard PTS sandbox kit.
Payload Encryption Flows:
• C# encrypt request -> Mastercard > C# decrypt response
This flow fails every time on the C# decrypt response, Java has no issues C# seems to not be able to decrypt it
Stack:
Mastercard.Developer.ClientEncryption.Core.Encryption.EncryptionException: Payload decryption failed!
---> System.ArgumentException: The specified nonce is not a valid size for this algorithm. (Parameter 'nonce')
at System.Security.Cryptography.AesGcm.CheckParameters(ReadOnlySpan1 plaintext, ReadOnlySpan
1 ciphertext, ReadOnlySpan1 nonce, ReadOnlySpan
1 tag)
at System.Security.Cryptography.AesGcm.Decrypt(Byte[] nonce, Byte[] ciphertext, Byte[] tag, Byte[] plaintext, Byte[] associatedData)
at Mastercard.Developer.ClientEncryption.Core.Encryption.AES.AesGcm.Decrypt(Byte[] secretKeyBytes, JweObject jweObject) in C:\Users\MohamedAShaheedMadan\source\repos\stcpay-middleware-dotnet\StcPay.Middleware\Common\Mastercard.Developer.ClientEncryption.Core\Encryption\AES\AesGcm.cs:line 33
at Mastercard.Developer.ClientEncryption.Core.Encryption.JWE.JweObject.Decrypt(JweConfig config) in C:\Users\MohamedAShaheedMadan\source\repos\stcpay-middleware-dotnet\StcPay.Middleware\Common\Mastercard.Developer.ClientEncryption.Core\Encryption\JWE\JweObject.cs:line 38
at Mastercard.Developer.ClientEncryption.Core.Encryption.JWE.JweEncryption.DecryptPayloadPath(JToken payload, String jsonPathIn, String jsonPathOut, JweConfig config) in C:\Users\MohamedAShaheedMadan\source\repos\stcpay-middleware-dotnet\StcPay.Middleware\Common\Mastercard.Developer.ClientEncryption.Core\Encryption\JWE\JweEncryption.cs:line 77
at Mastercard.Developer.ClientEncryption.Core.Encryption.JWE.JweEncryption.DecryptPayload(String payload, JweConfig config) in C:\Users\MohamedAShaheedMadan\source\repos\stcpay-middleware-dotnet\StcPay.Middleware\Common\Mastercard.Developer.ClientEncryption.Core\Encryption\JWE\JweEncryption.cs:line 50
--- End of inner exception stack trace ---
at Mastercard.Developer.ClientEncryption.Core.Encryption.JWE.JweEncryption.DecryptPayload(String payload, JweConfig config) in C:\Users\MohamedAShaheedMadan\source\repos\stcpay-middleware-dotnet\StcPay.Middleware\Common\Mastercard.Developer.ClientEncryption.Core\Encryption\JWE\JweEncryption.cs:line 56
at PTSCommunicationWarper.Controllers.PTSCommController.Decrypt(EncryptRequest request) in C:\Users\MohamedAShaheedMadan\source\repos\stcpay-middleware-dotnet\StcPay.Middleware\PTSCommunicationWarper\Controllers\PTSCommController.cs:line 76
at lambda_method1(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
To Reproduce:
var config = JweConfigBuilder.AJweEncryptionConfig()
.WithEncryptionCertificate(encryptionCertificate)
.WithDecryptionKey(decryptionKey).WithEncryptionPath("$", "$").WithDecryptionPath("$.encryptedValue", "$").WithEncryptedValueFieldName(encryptedValueFieldName: "encryptedValue")
.Build();
var dec = JweEncryption.DecryptPayload(response.Body, config);
Related issues/PRs
Has a similar issue/PR been reported/opened before?
Suggest a fix/enhancement
If you can't fix the bug yourself, perhaps you can point to what might be causing the problem (line of code or commit), or simply make a suggestion.
If this is a Feature request, please check out this.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.