react-native-rsa-native
react-native-rsa-native copied to clipboard
Decrypting crash in ios
I made a small program that will crash in ios instantly:
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { RSA } from 'react-native-rsa-native';
export default class App extends Component<{}> {
render() {
console.log("Starting");
// This line will succeed
//const encryptedMessage = 'oDPvLJ254KRxmim1Oe03mJY7Uhbl9zWSH9beynkDFhItfD3JqwfIG0u4hRoFLwLv2VpB2qlu7Ah5ZrRQaBTapmF9+dkPHPGpnF2Ze6bKdLmyc8+1iXXt8ZIM/Nrl3w/Kcb0IWPBn4AEIBycy0oeBlDYVIl6NnA3nspoVCHaXdP+fi4G7Mp4xyFTYSK+RcTe9IgLx6ZX4/IxykLymaUgdRJu09ZlJ5ubJ0l8KC+af+9NUMwoYdIM4hUckA+hOOtSO2DFkxmeFzwrX1rR97H08h3OoIX32m9Id0KJP7aoq9tBnAhnTnbkifgz2uD1aqm4IJeUS2hL07HDSZXEsXdsKJQ==';
// This line will crash
const encryptedMessage = 'aoDPvLJ254KRxmim1Oe03mJY7Uhbl9zWSH9beynkDFhItfD3JqwfIG0u4hRoFLwLv2VpB2qlu7Ah5ZrRQaBTapmF9+dkPHPGpnF2Ze6bKdLmyc8+1iXXt8ZIM/Nrl3w/Kcb0IWPBn4AEIBycy0oeBlDYVIl6NnA3nspoVCHaXdP+fi4G7Mp4xyFTYSK+RcTe9IgLx6ZX4/IxykLymaUgdRJu09ZlJ5ubJ0l8KC+af+9NUMwoYdIM4hUckA+hOOtSO2DFkxmeFzwrX1rR97H08h3OoIX32m9Id0KJP7aoq9tBnAhnTnbkifgz2uD1aqm4IJeUS2hL07HDSZXEsXdsKJQ==';
const privateKey = '-----BEGIN RSA PRIVATE KEY-----MIIEowIBAAKCAQEA8UETY2xfp+Qf2S/9nOZ959CI6SthNWnWD2D9KBH38fV+mTrXTItu9PETbBjfbGKU89xIlNCPg7JNuwiAUNxnK5KgCfInqe9Ttz4aoEAqzRAgdqCxmg+OQNJQBDxG8ynmO1TZ80CDKKH54GRhNo7/ymLsOyHkIU7180Ht7XdM1fx2prMWW4OMNH9Y0KzR5lTBpUINpjODkAYIJWOXbZ0xZUlNSGSWiN8M5ZmO3lnUn72uQ3lpTGXnkLGv+6vQcY+ER5yyEq+Mr0Ghx/Scx9EoNarT6rReoGd6FpH6RTWq2U0uOs5S0XHR0W6vYpeDDEhTyceDxj1yRV1/1vVzleYrbQIDAQABAoIBAAGMJa1jv4hkDdX55f5yz+YhyYcHN4D41mI6ZxEHOyTPIiPqVqvtlfaC+ox6/H7SLdskk6zfWoeBW3I21vqHZlGcmMnc4GcezoBtF9opWvAgYx8NifLkulEG24S7+D6ItgikhnRtnLz1N2qHSCrhhVT39wBoGOC9Jlo/dPqIp3a/gFKV8JoNfYRq2iz8Wq+orWlAqBEyG8KNuAiqhee4HFUGL4HV2SbfgEcpQvNnpbkJ+1+4iu5sd1FLTS3hBcHcovyXqek57gEIj9kflO92lABQIsM4aNGzIEwOyF1du+423+900tpqy12W26YfGQRR+6f0kyqaVnJZbxqxSuz2Y7ECgYEA/drkCrhlhXwG0nWelpqhMhQKx7AUgfizKojKYi5LsqlutdtQt3oM5lE0lNDOkIplPJSOBuDaCy3aoeGs0P7EEPPgAY+duomRRp0spmLC5pSx4qTLRQ31KmLRoDLU9P738DaWFImOxf9t84RmbPDBPlHUHEvntRU3X0rcr7/16vUCgYEA80rtpREv8ux06mkGG8hSyjca0kL9o967EmZx2BDsfi9O2W2XixCdmq0ybFH+7/MEB6fyUMJuR4MA6LioZbpgE28Hok7qQi8BxPAOWLMEzE072E+R6KTkRqiEg8xyJl13UMZZyv55b+hwpLK4zq6eoCxv7gnABMCnfCoCoI/QY5kCgYEAxVBqiFqjromk09lQl0dBnCcv6d7XUd75hEom5QGPHSPNRdVee/6GIE9mS3Wx2W95GQlvC7GiSaYulj1PknMz+ulUaGI0+1UKcpSgrAN/8rIJQl1NEjOzKGr+/UIFfRjhpvkG1pfFPek4kVuMMYlA6yu3bvcg9wOysoMB3imbADECgYAkvopJxeDCBahaxuXfSFAIrm3kl62LFFaYntRO16+AF1EHUZ/zptzGwaW96lxgjQlsxpa4T8UsE8MNYuY8Bvv/s2MpxlVnDYZs4fyotNDisj95mfrlchHwAf+RkE0lMjSVBIAHQovAtRBeL4ft3z2h31RAVUSk8xvYite+vDmy8QKBgD3IIxh60ZOaj16Kb6KwWeDcmz0E/u6BvBoomRY1JvP4HiIrzSO/TnFOX+BR20M219mxY3vLpCZFv11B1rRi19dmywVLS3nVyObpnmMyfIHKuYCfzmpwYtPG08khOMo4KVO5i8QIXYdu/5Xc1MGUWuNSyK5/1vB7gwBFj0TpE3dA-----END RSA PRIVATE KEY-----';
RSA.decrypt(encryptedMessage, privateKey).then(() => {
console.log("SUCCESS");
});
return (
<View>
<Text>hi</Text>
</View>
);
}
}
The private key there was generated just for this example. The top encrypted message was made with the paired public key, and then I just added an 'a' to the front of it to cause a crash.
The crash I get is:
Thread 7 Crashed:: Dispatch queue: com.apple.root.default-qos
0 CoreData 0x00007fff23aa6bb5 CFDataGetLength + 5
1 com.apple.Security 0x00007fff2bb583bd SecRSAPrivateKeyCopyOperationResult + 280
2 com.apple.Security 0x00007fff2bb386c7 SecKeyRunAlgorithmAndCopyResult + 216
3 com.apple.Security 0x00007fff2bb3be96 __SecKeyRSACopyDecryptedWithPadding_block_invoke + 35
4 com.apple.Security 0x00007fff2bb3c04c PerformWithBigEndianToCCUnit + 165
5 com.apple.Security 0x00007fff2bb3be30 SecKeyRSACopyDecryptedWithPadding + 272
6 com.apple.Security 0x00007fff2bb389ef SecKeyRunAlgorithmAndCopyResult + 1024
7 com.apple.Security 0x00007fff2bb38f86 SecKeyCreateDecryptedDataWithParameters + 113
8 org.reactjs.native.example.PAuth 0x0000000101b1ea21 __22-[RSANative _decrypt:]_block_invoke + 113
9 org.reactjs.native.example.PAuth 0x0000000101b1e8fe -[RSANative _decrypt:] + 542 (RSANative.m:210)
10 org.reactjs.native.example.PAuth 0x0000000101b1e658 -[RSANative decrypt:] + 120 (RSANative.m:182)
11 org.reactjs.native.example.PAuth 0x0000000101b18562 __42-[RNRSA decrypt:withKey:resolve:rejecter:]_block_invoke + 130 (RNRSA.m:59)
12 libdispatch.dylib 0x00007fff516ac810 _dispatch_call_block_and_release + 12
13 libdispatch.dylib 0x00007fff516ad781 _dispatch_client_callout + 8
14 libdispatch.dylib 0x00007fff516af829 _dispatch_queue_override_invoke + 834
15 libdispatch.dylib 0x00007fff516bcbfc _dispatch_root_queue_drain + 350
16 libdispatch.dylib 0x00007fff516bd39e _dispatch_worker_thread2 + 99
17 libsystem_pthread.dylib 0x00007fff518cd6b3 _pthread_wqthread + 583
18 libsystem_pthread.dylib 0x00007fff518cd3fd start_wqthread + 13
Looking at the ios code in RSANative.m doesn't yield any obvious fruit, but I wanted to expand to more eyeballs. It looks like (after a little testing) that most any garbage string put into decrypt will crash the whole app.
It looks like the crash is due to decrypting a message that base 64 decodes to something longer than 256 bytes.
Yep, this still exists, If decrypting fails for some reason, the whole app is crashing (version 2.0.3):
I have the same problem too. Is there any way to verify the message before decrypting?
Temporary solution ./node_modules/react-native-rsa-native/ios/RSAECNative.swift
(line 370) :
Would've been nice if this was fixed in 2.0.4. Still needs patching :/
I hope that could be fixed too. A simple package shouldn't crash the whole app when something goes wrong. Ideally it should throw an error but even returning null would be better than nothing, since at least we can handle it.
For those searching for the issue, the error is:
Fatal error: Unexpectedly found nil while unwrapping an Optional value
Edit: In my case it was crashing using data generated from node-rsa, and I fixed it by using the "pkcs1" encryption scheme (it's "pkcs1_oaep" by default). So it looks like this:
const keys = new NodeRSA();
keys.setOptions({ encryptionScheme: 'pkcs1' });
So it seems the RN lib is making some assumption on the private key padding scheme, which unfortunately is not documented anywhere. I'd submit a PR but the repo seems pretty dead, so probably not worth it.
@ptfly it works. Thanks.
@amitaymolko So is it possible for maintainers to fix the project?
added suggested fix in 2.0.5 please confirm it fixes your issue.
I haven't been working with this lib for a while so I have been maintaining it less, if anyone wants to become a maintainer please let me know