mastercard / client-encryption-nodejs 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
The package does not come with built-in ts declarations and it's not present on the DefinitelyTyped repository for external ts files
Hi,
I am trying to run the mocha test available in the repo (createTokenize API). However with that, I am using the sandbox credentials (consumerKey, oAuth privateKey) from the developer portal. I was unable to find the certificate (mastercard) for field level encryption in the portal. So I am using the one in this repo -> test/res/test_certificate.cert
However on hitting the API call, I am getting following response:
{
"errorCode": "CRYPTOGRAPHY_ERROR",
"errorDescription": "Cryptography Error",
"errors": [
{
"source": "INPUT",
"reasonCode": "CRYPTOGRAPHY_ERROR",
"description": "Cryptography Error"
}
],
"responseId": "123456",
"supportsAuthentication": false
}
Any pointers on what could be wrong I am doing here?
Description
There seems to be a mismatch between the format that MDES uses for the private keys it issues (ref: item 3, section 6 of this document) and the one that is expected by the FieldLevelEncryption
constructor.
I'm not sure if this is indeed a bug - I haven't checked whether some file format or an adaptated version of the MDES private key file would work - but, since this is a helper lib for MDES, it should integrate as effortlessly as possible with it.
To Reproduce
const config = {
paths: [
{}
],
oaepPaddingDigestAlgorithm: '',
ivFieldName: '',
encryptedKeyFieldName: '',
encryptedValueFieldName: '',
oaepHashingAlgorithmFieldName: '',
publicKeyFingerprintFieldName: '',
publicKeyFingerprintType: "",
dataEncoding: 'hex',
encryptionCertificate: "/path/to/Public-Key-Encrypt.crt",
privateKey: "/path/to/Private-Key-Decrypt.pem"
};
require('mastercard-client-encryption').FieldLevelEncryption(config);
(This is not necessarily a valid config, but it's the minimum necessary config to trigger the bug)
When this code is executed, the following error is thrown:
/myproject/node-forge/lib/asn1.js:491
throw error;
^
Error: Too few bytes to read ASN.1 value.
at _fromDer (/myproject/node-forge/lib/asn1.js:487:19)
at _fromDer (/myproject/node-forge/lib/asn1.js:524:20)
at Object.asn1.fromDer (/myproject/node-forge/lib/asn1.js:448:10)
at loadPrivateKey (/myproject/mastercard-client-encryption/lib/mcapi/crypto/crypto.js:182:50)
at new Crypto (/myproject/mastercard-client-encryption/lib/mcapi/crypto/crypto.js:22:23)
at Object.FieldLevelEncryption (/myproject/mastercard-client-encryption/lib/mcapi/fle/field-level-encryption.js:15:17)
at Object.<anonymous> (/home/bernardo/Dev/basistheory/mdes-bug-report/app.js:16:41)
at Module._compile (internal/modules/cjs/loader.js:1085:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
at Module.load (internal/modules/cjs/loader.js:950:32) {
available: 1675,
remaining: 43,
requested: 45
}
Expected behavior
The FieldLevelEncryption
constructor should accept and correctly parse the payload encryption private key that was issued
Suggest a fix/enhancement
Substituting the contents of this line for:
return forge.pki.privateKeyFromPem(privateKeyContent);
caused the FieldLevelEncryption
construction to work
im having dependecy vulnerbility
can you plz merge dependabot's node-forge 0.10.0 pull request?
#18
The response payload is returning a body that is undefined
.
In the code snippet, after calling fle.ecrypt(), when i log the variable to the console:
let responsePayload = fle.encrypt("/resource1", payload);
console.log(responsePayload)
it displays the following:
``` { header: { path: { to: [Object] } }, body: undefined } ````
Below is the code - any help is much appreciated.thanks !
const clientEncryption = require('mastercard-client-encryption');
const config = {
paths: [
{
path: "/resource",
toEncrypt: [
{
/* path to element to be encrypted in request json body /
element: "path.to.foo",
/ path to object where to store encryption fields in request json body /
obj: "path.to.encryptedFoo"
}],
toDecrypt: [
{
/ path to element where to store decrypted fields in response object /
element: "path.to.encryptedFoo",
/ path to object with encryption fields */
obj: "path.to.foo"
}
]
}
],
ivFieldName: 'iv',
encryptedKeyFieldName: 'encryptedKey',
encryptedValueFieldName: 'encryptedData',
dataEncoding: 'hex',
encryptionCertificate: './certificate.pem',
publicKeyFingerprintType: "certificate",
oaepPaddingDigestAlgorithm: 'SHA-256'
// privateKey: '',
// ivHeaderName: "x-iv",
// EncryptedKeyHeaderName: "x-encrypted-key"
};
const payload =
{
"path": {
"to": {
"foo": {
"sensitive": "this is a secret!"
}
}
}
};
const fle = new clientEncryption.FieldLevelEncryption(config);
console.log(fle)
let responsePayload = fle.encrypt("/resource1", payload);
console.log(responsePayload)
i got that error when i try to call the encrypt method .. that's the code:
const fle = new require('mastercard-client-encryption').FieldLevelEncryption(config);
let encryptedRequestPayload = fle.encrypt(endpoint, header, body);
what should fle return ?? it returns undefined always ?
I am trying to use this library, following the read me, i get an error on this line
let responsePayload = fle.encrypt("/resource1", header, payload);
ReferenceError: header is not defined
Its unclear from the read me how the header should be defined.
Any help is appreciated, thanks
Hello,
I am using my private and cert.pem file in config, File is available in folder but still the code give me below error.
encryptionCertificate: fs.readFileSync( path.resolve(__dirname, "../public/images/demo/m8.demo.cert.pem") ), privateKey: fs.readFileSync( path.resolve(__dirname, "../public/images/demo/m8.demo.key.no_pasword.key") ),
(node:19736) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open '-----BEGIN CERTIFICATE----- MIERE.....ERERER -----END CERTIFICATE----- ' at Object.openSync (fs.js:439:3) at Object.readFileSync (fs.js:344:35) at readPublicCertificate (D:\node project\MiaWallet\node_modules\mastercard-client-encryption\lib\mcapi\crypto\crypto.js:189:33) at new Crypto (D:\node project\MiaWallet\node_modules\mastercard-client-encryption\lib\mcapi\crypto\crypto.js:18:32) at new FieldLevelEncryption (D:\node project\MiaWallet\node_modules\mastercard-client-encryption\lib\mcapi\fle\field-level-encryption.js:15:17) at addCard (D:\node project\MiaWallet\controller\index.js:209:17) at Layer.handle [as handle_request] (D:\node project\MiaWallet\node_modules\express\lib\router\layer.js:95:5) at next (D:\node project\MiaWallet\node_modules\express\lib\router\route.js:137:13) at Route.dispatch (D:\node project\MiaWallet\node_modules\express\lib\router\route.js:112:3) at Layer.handle [as handle_request] (D:\node project\MiaWallet\node_modules\express\lib\router\layer.js:95:5) (node:19736) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) (node:19736) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. (node:19736) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open '-----BEGIN CERTIFICATE--
Description
The ivFieldName
configuration property is ignored during encryption, iv
field name is used as default.
To Reproduce
ivFieldName="foobar"
{
/*...*/
ivFieldName: 'foobar',
encryptedKeyFieldName: 'encryptedKey',
encryptedValueFieldName: 'encryptedData',
oaepHashingAlgorithmFieldName: 'oaepHashingAlgorithm',
/*...*/
}
Actual behavior
The encrypted payload set the IV data in the iv
field, ignoring the configured ivFieldName
.
Expected behavior
The encrypted payload should set the computed IV data in the foobar
property, as per configuration.
Description
RSA_padding_check_PKCS1_OAEP_mgf1 Error throw for JWE encryption mode
To Reproduce
Use Encrypting Entire Payloads From Java library https://github.com/Mastercard/client-encryption-java
Now Try to decrypt same in nodes js . Use same public and private key in both
const config = {
paths: [
{
toEncrypt: [
{
/* path to element to be encrypted in request json body */
element: "$",
/* path to object where to store encryption fields in request json body */
obj: "$",
},
],
toDecrypt: [
{
/* path to element where to store decrypted fields in response object */
element: "$",
/* path to object with encryption fields */
obj: "$",
},
],
},
],
encryptedValueFieldName: "encryptedData",
encryptionCertificate: "./testCertificate.cert",
keyStore: "./test_key.pem",
mode: "JWE"
};
const fle = new (require("mastercard-client-encryption").JweEncryption)(
config
);
const encryptedPayload = {
request: {
url : '/resource1'
},
body: {
encryptedData:'{{encryptedvalues}}'}
};
let responsePayload2 = fle.decrypt(encryptedPayload);
console.log('decrypted',responsePayload2);
Above result in error
node:internal/crypto/cipher:79
return method(data, format, type, passphrase, buffer, padding, oaepHash,
^
Error: error:04099079:rsa routines:RSA_padding_check_PKCS1_OAEP_mgf1:oaep decoding error
at Object.privateDecrypt (node:internal/crypto/cipher:79:12)
at JweCrypto.decryptData (C:\Users\smehta\LunchAndLearn\Data Encryption\node_modules\mastercard-client-encryption\lib\mcapi\crypto\jwe-crypto.js:122:32)
at JweEncryption.decryptBody (C:\Users\smehta\LunchAndLearn\Data Encryption\node_modules\mastercard-client-encryption\lib\mcapi\encryption\jwe-encryption.js:91:38)
at C:\Users\smehta\LunchAndLearn\Data Encryption\node_modules\mastercard-client-encryption\lib\mcapi\encryption\jwe-encryption.js:57:26
at Array.map (<anonymous>)
at JweEncryption.decrypt (C:\Users\smehta\LunchAndLearn\Data Encryption\node_modules\mastercard-client-encryption\lib\mcapi\encryption\jwe-encryption.js:55:35)
at Object.<anonymous> (C:\Users\smehta\LunchAndLearn\Data Encryption\mcdEncryptDemo.js:76:28)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10) at Module.load (node:internal/modules/cjs/loader:981:32) {
library: 'rsa routines',
function: 'RSA_padding_check_PKCS1_OAEP_mgf1',
reason: 'oaep decoding error',
code: 'ERR_OSSL_RSA_OAEP_DECODING_ERROR'
}
Expected behavior
Decrypted payload
Additional context
Bydefault Node js JWE crypto use following constant nodeCrypto.constants.RSA_PKCS1_OAEP_PADDING
and JAVA seems to be using some another padding or issue with iv length
Description
When encrypting the entire payload and assigning it to encryptedData, and subsequently making an API call, the response is received as an encryptedResponse object. In this case, while decrypting response object an error is thrown throw new Error("Input not valid");.
To Reproduce
JWE Config
{
"path": "/entirepayload",
"toEncrypt": [{ "element": "$", "obj": "$" }],
"toDecrypt": [{ "element": "encryptedResponse", "obj": "$" }],
"mode": "JWE",
"encryptedValueFieldName": "encryptedData",
"publicKeyFingerprintType": "certificate",
"dataEncoding": "base64",
"encryptionCertificate": "./test/res/test_certificate.cert",
keyStore: "./pkcs8_private_key.pem"
}
Request payload
const payload = {
sensitive: "this is a secret!",
sensitive2: "this is a super-secret!",
}
Encrypt the request
const jwe = new (require("mastercard-client-encryption").JweEncryption)(config);
let encryptedData = jwe.encrypt("/entirepayload", null, payload);
Now, Data is encrypted as below which is expecte
{
header: null,
body: {
encryptedData: 'eyJraWQiOiIxMDc3ZDIyMTk0Y2MyNzFkNTY1Y2Y2Mjg5YzJiMjY1Y2U4MDhhNDdlMDFiMzhiMjIyZWE4YWU4M2U5MWUxN2Q2IiwiY3R5IjoiYXBwbGljYXRpb24vanNvbiIsImFsZyI6IlJTQS1PQUVQLTI1NiIsImVuYyI6IkEyNTZHQ00ifQ.VaUDfEwds7/kQdQdhpQllSxAhCQrnILDHIF4dY6U-9D8Jg33rLkQMYRzNmEwA14KE0zNVqy2-r6yZ8U7wuksSap9K7jVdhF2XZmW-ytYedS79bOVWe3euNUvHgFSEVt53J67Ca80p8B6x9EeJnYcvQhHVkumVD-QEpb3sk0dIUfo29LVugxKrdJDYKECtXjV1BYrZY0aZ26k-RcqyJdngFphknRDdQpXves4dV3A7qvBHXe65aNrKOUMTpIJ4iTGSNGj4/ismrMj3OENx4aBuLA9igVZgpTEaX1IPwmpIBir/Zl/ZcV567i2FcUoFfjNt63olIMnd4axGwvM3/QPug.ez7IRvsts3LETjGJNU2HgA.OApjJMlmPacg1pdySaFwMrknJ/USUVdFB9dCvwypxPvescKuGkyL-aZNtr307YYF0GmxzBVQ9ZS7wdRSW8xzm6NdCyqmiHEe.7VSy2mfxi5JDLieN135A2A'
}
}
When I send the encryptedData to my API, It will return the response object as encryptedResponse, as shown below.
You can simulate the API behavior like below.
encryptedData.body.encryptedResponse = encryptedData.body.encryptedData;
delete encryptedData.body.encryptedData;
body: {
encryptedResponse: 'eyJraWQiOiIxMDc3ZDIyMTk0Y2MyNzFkNTY1Y2Y2Mjg5YzJiMjY1Y2U4MDhhNDdlMDFiMzhiMjIyZWE4YWU4M2U5MWUxN2Q2IiwiY3R5IjoiYXBwbGljYXRpb24vanNvbiIsImFsZyI6IlJTQS1PQUVQLTI1NiIsImVuYyI6IkEyNTZHQ00ifQ.VaUDfEwds7/kQdQdhpQllSxAhCQrnILDHIF4dY6U-9D8Jg33rLkQMYRzNmEwA14KE0zNVqy2-r6yZ8U7wuksSap9K7jVdhF2XZmW-ytYedS79bOVWe3euNUvHgFSEVt53J67Ca80p8B6x9EeJnYcvQhHVkumVD-QEpb3sk0dIUfo29LVugxKrdJDYKECtXjV1BYrZY0aZ26k-RcqyJdngFphknRDdQpXves4dV3A7qvBHXe65aNrKOUMTpIJ4iTGSNGj4/ismrMj3OENx4aBuLA9igVZgpTEaX1IPwmpIBir/Zl/ZcV567i2FcUoFfjNt63olIMnd4axGwvM3/QPug.ez7IRvsts3LETjGJNU2HgA.OApjJMlmPacg1pdySaFwMrknJ/USUVdFB9dCvwypxPvescKuGkyL-aZNtr307YYF0GmxzBVQ9ZS7wdRSW8xzm6NdCyqmiHEe.7VSy2mfxi5JDLieN135A2A'
}
Now, when I try to decrypt the encrypted response I get below error
const response = {};
response.request = { url: "/entirepayload" };
response.body =encryptedData.body;
let decryptedPayload = jwe.decrypt(response);
mastercard-client-encryption/lib/mcapi/crypto/jwe-crypto.js:103
throw new Error("Input not valid");
^
Error: Input not valid
at JweCrypto.decryptData (/Users//Workspace/temp/test-jwe/node_modules/mastercard-client-encryption/lib/mcapi/crypto/jwe-crypto.js:103:13)
at JweEncryption.decryptBody (/Users//Workspace/temp/test-jwe/node_modules/mastercard-client-encryption/lib/mcapi/encryption/jwe-encryption.js:88:38)
at /Users//Workspace/temp/test-jwe/node_modules/mastercard-client-encryption/lib/mcapi/encryption/jwe-encryption.js:53:26
at Array.map (<anonymous>)
at JweEncryption.decrypt (/Users/Workspace/temp/test-jwe/node_modules/mastercard-client-encryption/lib/mcapi/encryption/jwe-encryption.js:52:35)
at Object.<anonymous> (/Users//Workspace/temp/test-jwe/app.js:61:28)
at Module._compile (internal/modules/cjs/loader.js:1085:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
at Module.load (internal/modules/cjs/loader.js:950:32)
at Function.Module._load (internal/modules/cjs/loader.js:790:12)
Additional context
Add any other context about the problem here (OS, language version, etc..).
Related issues/PRs
PR: (#64)
cardInfo
is now fundingAccountInfo
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.