react-native-rsa-native icon indicating copy to clipboard operation
react-native-rsa-native copied to clipboard

Decrypting crash in ios

Open martaaay opened this issue 4 years ago • 8 comments

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.

martaaay avatar Oct 25 '19 18:10 martaaay

It looks like the crash is due to decrypting a message that base 64 decodes to something longer than 256 bytes.

martaaay avatar Oct 25 '19 18:10 martaaay

Yep, this still exists, If decrypting fails for some reason, the whole app is crashing (version 2.0.3): Screenshot 2021-04-21 at 15 56 36

ptfly avatar Apr 21 '21 14:04 ptfly

I have the same problem too. Is there any way to verify the message before decrypting?

Richtervn avatar May 05 '21 09:05 Richtervn

Temporary solution ./node_modules/react-native-rsa-native/ios/RSAECNative.swift (line 370) : Screenshot 2021-05-11 at 15 52 43

ptfly avatar May 11 '21 12:05 ptfly

Would've been nice if this was fixed in 2.0.4. Still needs patching :/

ptfly avatar Sep 14 '21 12:09 ptfly

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.

laurent22 avatar Oct 02 '21 15:10 laurent22

@ptfly it works. Thanks.

@amitaymolko So is it possible for maintainers to fix the project?

euthribeiro avatar Jan 05 '22 16:01 euthribeiro

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

amitaymolko avatar Jan 06 '22 06:01 amitaymolko