CryptoStream in .NET does not decrypt encrypted file from objective-C

試著忘記壹切 提交于 2019-12-11 23:57:13

问题


I am implementing compatible binary file encryption/decryption between .NET and Objective-C apps. I am using RNCryptor package on Objective-C side. As far as I reached, I am able to encrypt/decrypt strings, but file encryption is troubling me. The problem is, when I read file and encrypt its data and write it to a file, it doesn't decrypt in .NET app. If I calculate Base64 string of encrpted data and decrypt that in .NET - creating byte array from Base64 string and decrypt with same login as of file, it decrypts. Is there any difference between writing encrypted data to file in Objective C and .NETCryptoStream?

Or am I missing something basic? Code for encrypting file in objective C is :-

  RNEncryptor *encryptor = [[RNEncryptor alloc] initWithSettings:kRNCryptorAES256Settings
                                                          password:password
                                                           handler:^(RNCryptor *cryptor, NSData *data) {
                                                               @autoreleasepool
                                                               {
                                                                   NSLog(@"6length of out data %d",[data length]);

                                                                   [encodedText appendString:[data base64EncodingWithLineLength:0]];
                                                                   [outputStream write:data.bytes maxLength:data.length];

                                                                   dispatch_semaphore_signal(semaphore);

                                                                   data = nil;
                                                                   if (cryptor.isFinished)
                                                                   {

                                                                       [outputStream close];
                                                                       NSLog(@"my encryptedText  %@",encodedText);
                                                                       encryptionError = cryptor.error;
                                                                       // call my delegate that I'm finished with decrypting
                                                                   }
                                                               }
                                                           }];
    encryptor.filesize=[attrs fileSize];
    while (inputStream.hasBytesAvailable)
    {
        @autoreleasepool
        {
            uint8_t buf[blockSize];
            NSUInteger bytesRead = [inputStream read:buf maxLength:blockSize];
            if (bytesRead > 0)
            {
                NSData *data = [NSData dataWithBytes:buf length:bytesRead];

            }
                total = total + bytesRead;
                [encryptor addData:data];

                dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            }
        }
    }

    [inputStream close];

    [encryptor finish];
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}

Decrypting

[encodedText appendString:[data base64EncodingWithLineLength:0]];

always works but file doesn't decrypt.


回答1:


Update:

RNEncryptor actually is a high level encryption api for doing aes right, while it has an adhoc ciphertext format it is the typcial construction. To match your dotnet code with it's on adhoc format, you will have to use RNCryptor keyForPassword:salt:settings: with RNCryptorKeyDerivationSettings matching your Rfc2898DeriveBytes. Such as:

   {
    .keySize = kCCKeySizeAES256,
    .saltSize = 16,
    .PBKDFAlgorithm = kCCPBKDF2,
    .PRF = kCCPRFHmacAlgSHA1,
    .rounds = 1000
   }

And use RNCryptorEngine for your aes encryption, and layout the ciphertext matching your adhoc .net format.

| IV (16 bytes) | Password Salt (16 bytes) | Ciphertext |

This is assuming the plaintext is already in the right format too

| message length (8 bytes) | const tag of some sort (8 bytes) | message | sha256 hash of message (32 bytes) |

You may just want to use iOS's built-in CCCryptor directly at this point rather than RNCryptor if you need to make the plaintext format too (i'm guessing you do).

Advisory:

for the benefit of others who come across this question, there are security issues with the with the poster's .net ciphertext construction, don't use it.

Previous Answer:

RNCryptor does authenticated encryption.

It should actually be compatible with my code from: Modern Examples of Symmetric Authenticated Encryption of a string (C#)

Then to decrypt, what was produced with RNEncryptor, use:

var plainText = AESThanHmac.SimpleDecryptWithPassword(encryptedMessage, password, nonSecretPayloadLength: 2);

The nonSecretPayloadLength is to 2, so that it will skip the RNEncryptor Header's version/option.




回答2:


Base64 encoding needs input size to be multiple of 3 (it transforms each 3 bytes to 4 chars). If it is not, it adds padding ('=' symbols), which will not be processed in stream.



来源:https://stackoverflow.com/questions/18590183/cryptostream-in-net-does-not-decrypt-encrypted-file-from-objective-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!