Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: cipher on android #399

Merged
merged 8 commits into from
Aug 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/build-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Clear up some disk space
run: |
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
sudo rm -rf "/usr/local/share/boost"
sudo rm -rf "$AGENT_TOOLSDIRECTORY"

- name: Setup JDK
uses: actions/setup-java@v4
with:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,6 @@ lint/tmp/

# Release
.npmrc

example0/
tsconfig.tsbuildinfo
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ android {
}

defaultConfig {
minSdkVersion safeExtGet('minSdkVersion', 23)
minSdkVersion safeExtGet('minSdkVersion', 28)
targetSdkVersion safeExtGet('targetSdkVersion', 31)
versionCode 1
versionName "1.0"
Expand Down
2 changes: 1 addition & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
QuickCrypto_compileSdkVersion=31
QuickCrypto_targetSdkVersion=31
QuickCrypto_ndkversion=21.4.7075529
QuickCrypto_minSdkVersion=23
QuickCrypto_minSdkVersion=28

android.useAndroidX=true
Binary file added bun.lockb
Binary file not shown.
6 changes: 5 additions & 1 deletion cpp/Cipher/MGLPublicCipher.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@ std::optional<jsi::Value> MGLPublicCipher::Cipher(jsi::Runtime& runtime,
return {};
}

if (EVP_PKEY_cipher_init(ctx.get()) <= 0) {
int init_ret = EVP_PKEY_cipher_init(ctx.get());
if (init_ret <= 0) {
if (init_ret == -2) {
throw std::runtime_error("operation is not supported by the public key algorithm");
}
return {};
}

Expand Down
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
4 changes: 2 additions & 2 deletions example/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
buildscript {
ext {
buildToolsVersion = "34.0.0"
minSdkVersion = 23
minSdkVersion = 28
compileSdkVersion = 34
targetSdkVersion = 34
ndkVersion = "25.1.8937393"
Expand All @@ -13,7 +13,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:8.3.1")
classpath('com.android.tools.build:gradle:8.3.1')
classpath("com.facebook.react:react-native-gradle-plugin")
}
}
1 change: 1 addition & 0 deletions example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#Fri Aug 09 17:48:30 EDT 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
Expand Down
1 change: 1 addition & 0 deletions example/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const pak = require('../package.json');
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: [
['@babel/plugin-transform-class-static-block'],
[
'module-resolver',
{
Expand Down
Binary file added example/bun.lockb
Binary file not shown.
17 changes: 9 additions & 8 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -323,12 +323,12 @@ PODS:
- react-native-quick-base64 (2.1.2):
- RCT-Folly (= 2021.07.22.00)
- React-Core
- react-native-quick-crypto (0.7.1):
- react-native-quick-crypto (0.7.2):
- OpenSSL-Universal
- RCT-Folly (= 2021.07.22.00)
- React
- React-Core
- react-native-safe-area-context (4.7.4):
- react-native-safe-area-context (4.10.8):
- React-Core
- React-NativeModulesApple (0.72.7):
- hermes-engine
Expand Down Expand Up @@ -443,9 +443,10 @@ PODS:
- RNCCheckbox (0.5.17):
- BEMCheckBox (~> 1.4)
- React-Core
- RNScreens (3.27.0):
- RNScreens (3.34.0):
- RCT-Folly (= 2021.07.22.00)
- React-Core
- React-RCTImage
- SocketRocket (0.6.1)
- Yoga (1.14.0)

Expand Down Expand Up @@ -602,11 +603,11 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
BEMCheckBox: 5ba6e37ade3d3657b36caecc35c8b75c6c2b1a4e
boost: 57d2868c099736d80fcd648bf211b4431e51a558
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5
FBLazyVector: 5fbbff1d7734827299274638deb8ba3024f6c597
FBReactNativeSpec: 638095fe8a01506634d77b260ef8a322019ac671
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
glog: fdfdfe5479092de0c4bdbebedd9056951f092c4f
hermes-engine: 9180d43df05c1ed658a87cc733dc3044cf90c00a
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
OpenSSL-Universal: 6e1ae0555546e604dbc632a2b9a24a9c46c41ef6
Expand All @@ -627,8 +628,8 @@ SPEC CHECKSUMS:
React-logger: 8edc785c47c8686c7962199a307015e2ce9a0e4f
react-native-fast-encoder: 6f59e9b08e2bc5a8bf1f36e1630cdcfd66dd18af
react-native-quick-base64: 61228d753294ae643294a75fece8e0e80b7558a6
react-native-quick-crypto: 2f44f5d04eef5d925f7a1c24074d711b4f3c99d1
react-native-safe-area-context: 2cd91d532de12acdb0a9cbc8d43ac72a8e4c897c
react-native-quick-crypto: bb6d9b08f7f4a86588369cd0421adcf5da1d992a
react-native-safe-area-context: b7daa1a8df36095a032dff095a1ea8963cb48371
React-NativeModulesApple: b6868ee904013a7923128892ee4a032498a1024a
React-perflogger: 31ea61077185eb1428baf60c0db6e2886f141a5a
React-RCTActionSheet: 392090a3abc8992eb269ef0eaa561750588fc39d
Expand All @@ -647,7 +648,7 @@ SPEC CHECKSUMS:
React-utils: 56838edeaaf651220d1e53cd0b8934fb8ce68415
ReactCommon: 5f704096ccf7733b390f59043b6fa9cc180ee4f6
RNCCheckbox: a3ca9978cb0846b981d28da4e9914bd437403d77
RNScreens: 3c2d122f5e08c192e254c510b212306da97d2581
RNScreens: 80369e822c4f123c3f076c9ea4141991c17770f9
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
Yoga: 4c3aa327e4a6a23eeacd71f61c81df1bcdf677d5

Expand Down
5 changes: 3 additions & 2 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"@react-navigation/native-stack": "^6.9.12",
"buffer": "^6.0.3",
"chai": "^5.0.0",
"eslint": "^8.4.1",
"events": "^3.3.0",
"mocha": "^10.2.0",
"react": "18.2.0",
Expand All @@ -35,9 +34,10 @@
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/plugin-transform-class-static-block": "^7.24.7",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native/gradle-plugin": "^0.75.0-main",
"@react-native/gradle-plugin": "0.74.87",
"@react-native/metro-config": "^0.73.2",
"@tsconfig/react-native": "^2.0.2",
"@types/chai": "^4.3.4",
Expand All @@ -48,6 +48,7 @@
"@types/react-test-renderer": "^18.0.0",
"@types/readable-stream": "^4.0.11",
"babel-plugin-module-resolver": "^5.0.0",
"eslint": "^8.4.1",
"metro-react-native-babel-preset": "0.76.8",
"prettier": "^2.4.1"
},
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 algo = 'aes-128-gcm';

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

const cipher = crypto.createCipheriv(algo, secretKey, iv);

const encryptedPayload = Buffer.concat([
cipher.update(payload, 'utf8'),
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(
algo,
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',
});
};

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

const publicKey = getPublicKeyInPEMFormat(publicKeySpkiBase64);
console.log('\n' + 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 });
});
});
Loading
Loading