Giter Club home page Giter Club logo

Comments (7)

scastro avatar scastro commented on July 18, 2024 2

I totally forgot about this, thanks for the reminder @indiandragon!

I can't share the entire code do to NDA stuff but I will share as much as I can.
I don't have access to the Java code in the server, so I will share as much as I can from the iOS app.

As I mentioned before my problem was to gather the "chunks" and build the keys to interact with the server. Send my public key and retrieve server public key from those chunks.

First, create all the keys needed:

    MIHRSAKeyFactory* factory = [[MIHRSAKeyFactory alloc] init];
    factory.preferedKeySize = MIHRSAKey1024;
    MIHKeyPair *keyPair = [factory generateKeyPair];
    MIHRSAPrivateKey* _clientPrivateKey = keyPair.private;
    MIHRSAPublicKey* _clientPublicKey = keyPair.public;

Then just get all the chunks from a JSON, this is basically read the chunks and make an NSArray. Each chunk is encrypted with my public key on the server and send it over to the app, so I have to decrypt each part to build the public server key.

To decrypt each chunk I do something like this:

    NSData* data = [self dataFromHexString:str];
    NSData *decryptedData = [_clientPrivateKey decrypt:data error:&error];
    if (error){
        NSLog(@"RSAManager - Error : %@",error);
        return nil;
    }
    NSString *decryptedString = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];

Then must gather all this chunks and build the public server key. Suppose you make an NSArray of strings with all the decrypted chunks, so you have to do something like this:

    NSString* key = @"";
    for (NSString* item in chain) {
        key = [key stringByAppendingString:[item stringByReplacingOccurrencesOfString:@"\n" withString:@""]];
        key = [key stringByReplacingOccurrencesOfString:@"-----BEGIN PUBLIC KEY-----" withString:@""];
        key = [key stringByReplacingOccurrencesOfString:@"-----END PUBLIC KEY-----" withString:@""];
    }

I have to add that stringByReplacingOccurrencesOfString in order to get the keys working, because each chunk came with that data. Probably there is a better way of doing this but in my tests this was the only that worked without issues.

After this, you just need to build the server public key:

    NSData* pem = [NSData MIH_dataByBase64DecodingString:str];
    //[_serverPublicKey setRsaPadding:RSA_PKCS1_OAEP_PADDING];
    MIHRSAPublicKey* _serverPublicKey = [[MIHRSAPublicKey alloc] initWithData:pem];

Padding depends on your configuration and the encryption used in the server, I just put it there so you can change that in the app, pretty simple.

After this is just send and receive encrypted packages. In my case, the encryption is only needed when the app sends some data (the responses were always raw info and don't need the entire RSA process). So, if you want to encrypt an string and send it over to the server, I built a method that gets an string and return the array of chunks to send to the server:

- (NSArray *)encryptStringForServer:(NSString*)str {
    NSError *error = nil;
    NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
    NSData* encryptedData = [_serverPublicKey encrypt:data error:&error];
    if (error){
        NSLog(@"RSAManager - Error : %@",error);
        return nil;
    }

    NSUInteger length = [encryptedData length];
    NSUInteger chunkSize = 100;
    NSUInteger offset = 0;
    NSMutableArray* chunksArray = [NSMutableArray array];
    do {
        NSUInteger thisChunkSize = length - offset > chunkSize ? chunkSize : length - offset;
        NSData* chunk = [NSData dataWithBytesNoCopy:(char *)[encryptedData bytes] + offset
                                             length:thisChunkSize
                                       freeWhenDone:NO];
        offset += thisChunkSize;
        [chunksArray addObject:chunk];
    } while (offset < length);

    NSMutableArray* result = [NSMutableArray array];
    for (NSData* chunk in chunksArray) {
        NSData* encryptedData = [_clientPrivateKey encrypt:chunk error:&error];
        if (error){
            NSLog(@"RSAManager - Error : %@",error);
            return nil;
        }
        [result addObject:[self NSDataToHex:encryptedData]];
    }
    return result;
}

I'm a completely newbie on the subject so probably there are better ways to solve this, this is just how I resolve this on my first app with this kind of encryption. Let me know if I can help in any other way.

from mihcrypto.

hohl avatar hohl commented on July 18, 2024

(Due to my own experience BouncyCastle and MIHCrypto work very well together. So don't worry about that.)

Your server response is 256 bytes long (which is equal to 2048 bits) while the key you used is 1024 bits long. This means the server has encrypted your message with a longer key then clientPublicKey. Maybe you are using the wrong key at server side or something went wrong during the transmission of the public key.

from mihcrypto.

hohl avatar hohl commented on July 18, 2024

Some other idea: Are you splitting your data into blocks of 1024 bytes before transmitting? Because that wouldn't work as expected. In RSA (at least in RSA_PKCS1_OAEP_PADDING mode, which is enabled per default) an random padding is added at the beginning and end of every encoded data package. So you loose some additional bytes. (For example when having a 1024 bits key, you can at maximum encrypt data of 983 bits, 41 bits are lost for padding.)

In addition to that, you need to know that the handling of long data is different in BouncyCastle and OpenSSL (which is the base for MIHCrypto). BouncyCastle will automatically split the data into packages of the maximum size and encrypt all of them, while OpenSSL stop and return an error.

Encrypting a lot of packages with the same key may be abused to leak the key itself. Because of this in general you will use RSA for key exchange only and use some symmetric cryptography to encrypt the data itself with the exchanged key.

from mihcrypto.

scastro avatar scastro commented on July 18, 2024

Thanks @hohl for all the info.

I changed the approach and do this. Send the public key to the server, encrypt the "hello" word in the app and the server with the same public key, and compare the bytes arrays (NSData vs HexArray) and are different....

Any ideas why this could happen? It should be the same right?

from mihcrypto.

scastro avatar scastro commented on July 18, 2024

Ok, I think we got it running. I will post the code later so it will help someone else with the same problem, basically a newbie like me :)

from mihcrypto.

indiandragon avatar indiandragon commented on July 18, 2024

Hi @scastro , it would be great if you could post your code as many come here to look for implementation criteria regarding bouncy castle on java & MIH in iOS.

from mihcrypto.

indiandragon avatar indiandragon commented on July 18, 2024

@scastro That's great of you to respond to my request immediately, I'll check with your implementation and revert if I need any clarifications from you.

from mihcrypto.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.