Skip to content

Commit

Permalink
fix: cipher on android
Browse files Browse the repository at this point in the history
  • Loading branch information
boorad committed Jul 30, 2024
1 parent 233ac94 commit 41d5da9
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 6 deletions.
2 changes: 1 addition & 1 deletion cpp/Cipher/MGLPublicCipherInstaller.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ FieldDefinition getPublicCipherFieldDefinition(
runtime, pkey, padding, digest, arguments[offset + 3], buf);

if (!out.has_value()) {
throw jsi::JSError(runtime, "Failed to decrypt");
throw jsi::JSError(runtime, "Failed Cipher Operation - " + name);
}

return out.value().getObject(runtime);
Expand Down
13 changes: 8 additions & 5 deletions cpp/MGLQuickCryptoHostObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,29 @@ MGLQuickCryptoHostObject::MGLQuickCryptoHostObject(
// publicEncrypt
this->fields.push_back(
getPublicCipherFieldDefinition<MGLPublicCipher::kPublic,
EVP_PKEY_encrypt_init, EVP_PKEY_encrypt>(
EVP_PKEY_encrypt_init,
EVP_PKEY_encrypt>(
"publicEncrypt", jsCallInvoker, workerQueue));

// privateDecrypt
this->fields.push_back(
getPublicCipherFieldDefinition<MGLPublicCipher::kPrivate,
EVP_PKEY_decrypt_init, EVP_PKEY_decrypt>(
EVP_PKEY_decrypt_init,
EVP_PKEY_decrypt>(
"privateDecrypt", jsCallInvoker, workerQueue));

// privateEncrypt
this->fields.push_back(
getPublicCipherFieldDefinition<MGLPublicCipher::kPrivate,
EVP_PKEY_sign_init, EVP_PKEY_sign>(
EVP_PKEY_sign_init,
EVP_PKEY_sign>(
"privateEncrypt", jsCallInvoker, workerQueue));

// publicDecrypt
this->fields.push_back(
getPublicCipherFieldDefinition<MGLPublicCipher::kPublic,
EVP_PKEY_verify_recover_init,
EVP_PKEY_verify_recover>(
EVP_PKEY_verify_recover_init,
EVP_PKEY_verify_recover>(
"publicDecrypt", jsCallInvoker, workerQueue));

// generateKeyPair
Expand Down
1 change: 1 addition & 0 deletions example/src/hooks/useTestList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import '../testing/Tests/HmacTests/HmacTests';
import '../testing/Tests/HashTests/HashTests';
import '../testing/Tests/CipherTests/CipherTestFirst';
import '../testing/Tests/CipherTests/CipherTestSecond';
import '../testing/Tests/CipherTests/test398';
import '../testing/Tests/CipherTests/PublicCipherTests';
import '../testing/Tests/CipherTests/generateKey';
import '../testing/Tests/CipherTests/GenerateKeyPairTests';
Expand Down
104 changes: 104 additions & 0 deletions example/src/testing/Tests/CipherTests/test398.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import type { BinaryLikeNode } from './../../../../../src/Utils';
// import { Buffer } from 'buffer';
import { Buffer } from '@craftzdog/react-native-buffer';
import crypto from 'react-native-quick-crypto';
import { describe, it } from '../../MochaRNAdapter';
import { expect } from 'chai';

type EncryptRequest = {
payload: string;
publicKey: ArrayBuffer;
};
type EncryptResponse = {
KEY: string;
IV: string;
PAYLOAD: string;
secretKey: BinaryLikeNode;
};

const encrypt = ({ payload, publicKey }: EncryptRequest): EncryptResponse => {
const secretKey = crypto.randomBytes(16);
const iv = crypto.randomBytes(16);

const cipher = crypto.createCipheriv('aes-128-gcm', secretKey, iv);

const encryptedPayload = Buffer.concat([
cipher.update(payload),
cipher.final(),
cipher.getAuthTag(),
]).toString('base64');

const encryptedSessionKey = crypto.publicEncrypt(
{
key: publicKey,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
},
secretKey
);

return {
KEY: encryptedSessionKey.toString('base64'),
IV: iv.toString('base64'),
PAYLOAD: encryptedPayload,
secretKey,
};
};

const decrypt = ({
response,
secretKey,
}: {
response: EncryptResponse;
secretKey: BinaryLikeNode;
}) => {
const { IV, PAYLOAD } = response;

const decipher = crypto.createDecipheriv(
'aes-128-gcm',
secretKey,
Buffer.from(IV, 'base64')
);

const encryptedPayload = Buffer.from(PAYLOAD, 'base64');
let decrypted = decipher.update(
Buffer.from(encryptedPayload.subarray(0, encryptedPayload.length - 16))
);
decrypted = Buffer.concat([decrypted, decipher.final()]);

return JSON.parse(decrypted.toString('utf8'));
};

const getPublicKeyInPEMFormat = (key: string): ArrayBuffer => {
return crypto
.createPublicKey({
key: Buffer.from(key, 'base64'),
format: 'der',
type: 'spki',
})
.export({
type: 'spki',
format: 'pem',
});
};

// export { decrypt, encrypt, getPublicKeyInPEMFormat };

describe('test398', () => {
it('test398', () => {
const publicKeySpkiBase64 =
'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENlFpbMBNfCY6Lhj9A/clefyxJVIXGJ0y6CcZ/cbbyyebvN6T0aNPvpQyFdUwRtYvFHlYbqIZOM8AoqdPcnSMIA==';

const publicKey = getPublicKeyInPEMFormat(publicKeySpkiBase64);
console.log({ publicKey });
const encrypted = encrypt({
payload: JSON.stringify({ a: 1 }),
publicKey,
});
console.log({ encrypted });
const { response: decrypted } = decrypt({
response: encrypted,
secretKey: encrypted.secretKey,
});
expect(decrypted).to.equal({ a: 1 });
});
});

0 comments on commit 41d5da9

Please sign in to comment.