Coder Social home page Coder Social logo

rncryptor-objc's Introduction

RNCryptor

Cross-language AES Encryptor/Decryptor data format.

The primary target is Objective-C, but implementations are available in C++, C#, Java, PHP, Python, Javascript, and Ruby.

The data format includes all the metadata required to securely implement AES encryption, as described in "Properly encrypting with AES with CommonCrypto," and iOS 6 Programming Pushing the Limits, Chapter 15. Specifically, it includes:

  • AES-256 encryption
  • CBC mode
  • Password stretching with PBKDF2
  • Password salting
  • Random IV
  • Encrypt-then-hash HMAC

Basic Objective-C Usage

The most common in-memory use case is as follows:

NSData *data = [@"Data" dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSData *encryptedData = [RNEncryptor encryptData:data
                                   	withSettings:kRNCryptorAES256Settings
                                          password:aPassword
                                             error:&error];

This generates an NSData including a header, encryption salt, HMAC salt, IV, ciphertext, and HMAC. To decrypt this bundle:

NSData *decryptedData = [RNDecryptor decryptData:encryptedData
                                    withPassword:aPassword
                                           error:&error];

Note that RNDecryptor does not require settings. These are read from the header.

Asynchronous use

RNCryptor suports asynchronous use, specifically designed to work with NSURLConnection. This is also useful for cases where the encrypted or decrypted data will not comfortably fit in memory. If the data will comfortably fit in memory, asynchronous operation is best acheived using dispatch_async().

To operate in asynchronous mode, you create an RNEncryptor or RNDecryptor, providing it a handler. This handler will be called as data is encrypted or decrypted. As data becomes available, call addData:. When you reach the end of the data call finish.

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
  [self.encryptedData addData:[self.cryptor addData:data]];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
  [self.cryptor finish];
}

// Other connection delegates

- (void)decryptionDidFinish {
  if (self.cryptor.error) {
    // An error occurred. You cannot trust encryptedData at this point
  }
  else {
    // self.encryptedData is complete. Use it as you like
  }
  self.encryptedData = nil;
  self.cryptor = nil;
  self.connection = nil;
}

- (void)decryptRequest:(NSURLRequest *)request {
  self.encryptedData = [NSMutableData data];
  self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
  self.cryptor = [[RNDecryptor alloc] initWithPassword:self.password
                                               handler:^(RNCryptor *cryptor, NSData *data) {
                                                   [self.decryptedData appendData:data];
                                                   if (cryptor.isFinished) {
                                                     [self decryptionDidFinish];
                                                   }
                                                 }];
}

Async and Streams

When performing async operations on streams, the data can come very quickly (particularly if you're reading from a local file). If you use RNCryptor in a naïve way, you'll queue a work blocks faster than the engine can process them and your memory usage will spike. This is particularly true if there's only one core, such as on an iPad 1. The solution is to only dispatch new work blocks as the previous work blocks complete.

// Make sure that this number is larger than the header + 1 block.
// 33+16 bytes = 49 bytes. So it shouldn't be a problem.
int blockSize = 32 * 1024;

NSInputStream *cryptedStream = [NSInputStream inputStreamWithFileAtPath:@"C++ Spec.pdf"];
NSOutputStream *decryptedStream = [NSOutputStream outputStreamToFileAtPath:@"/tmp/C++.crypt" append:NO];

[cryptedStream open];
[decryptedStream open];

// We don't need to keep making new NSData objects. We can just use one repeatedly.
__block NSMutableData *data = [NSMutableData dataWithLength:blockSize];
__block RNEncryptor *decryptor = nil;

dispatch_block_t readStreamBlock = ^{
  [data setLength:blockSize];
  NSInteger bytesRead = [cryptedStream read:[data mutableBytes] maxLength:blockSize];
  if (bytesRead < 0) {
    // Throw an error
  }
  else if (bytesRead == 0) {
    [decryptor finish];
  }
  else {
    [data setLength:bytesRead];
    [decryptor addData:data];
    NSLog(@"Sent %ld bytes to decryptor", (unsigned long)bytesRead);
  }
};

decryptor = [[RNEncryptor alloc] initWithSettings:kRNCryptorAES256Settings
                                         password:@"blah"
                                          handler:^(RNCryptor *cryptor, NSData *data) {
                                            NSLog(@"Decryptor recevied %ld bytes", (unsigned long)data.length);
                                            [decryptedStream write:data.bytes maxLength:data.length];
                                            if (cryptor.isFinished) {
                                              [decryptedStream close];
                                              // call my delegate that I'm finished with decrypting
                                            }
                                            else {
                                              // Might want to put this in a dispatch_async(), but I don't think you need it.
                                              readStreamBlock();
                                            }
                                          }];

// Read the first block to kick things off    
readStreamBlock();

I'll eventually get this into the API to simplify things. See Cyrille's SO question for more discussion. Pull requests welcome.

Building

Comes packaged as a static library, but the source files can be dropped into any project. The OpenSSL files are not required.

Requires Security.framework.

Supports 10.6+ and iOS 4+.

The current file format is v3. To read v1 files (see Issue #44), you need to set the compile-time macro RNCRYPTOR_ALLOW_V1_BAD_HMAC. It is not possible to write v1 files anymore.

Design considerations

RNCryptor has several design goals, in order of importance:

Easy to use correctly for most common use cases

The most critical concern is that it be easy for non-experts to use RNCryptor correctly. A framework that is more secure, but requires a steep learning curve on the developer will either be not used, or used incorrectly. Whenever possible, a single line of code should "do the right thing" for the most common cases.

This also requires that it fail correctly and provide good errors.

Reliance on CommonCryptor functionality

RNCryptor has very little "security" code. It relies as much as possible on the OS-provided CommonCryptor. If a feature does not exist in CommonCryptor, then it generally will not be provided in RNCryptor.

Best practice security

Wherever possible within the above constraints, the best available algorithms are applied. This means AES-256, HMAC+SHA1, and PBKDF2:

  • AES-256. While Bruce Schneier has made some interesting recommendations regarding moving to AES-128 due to certain attacks on AES-256, my current thinking is in line with Colin Percival. PBKDF2 output is effectively random, which should negate related-keys attacks against the kinds of use cases we're interested in.

  • AES-CBC mode. This was a somewhat complex decision, but the ubiquity of CBC outweighs other considerations here. There are no major problems with CBC mode, and nonce-based modes like CTR have other trade-offs. See "Mode changes for RNCryptor" for more details on this decision.

  • Encrypt-then-MAC. If there were a good authenticated AES mode on iOS (GCM for instance), I would probably use that for its simplicity. Colin Percival makes good arguments for hand-coding an encrypt-than- MAC rather than using an authenticated AES mode, but in RNCryptor mananging the HMAC actually adds quite a bit of complexity. I'd rather the complexity at a more broadly peer-reviewed layer like CommonCryptor than at the RNCryptor layer. But this isn't an option, so I fall back to my own Encrypt-than-MAC.

  • HMAC+SHA256. No surprises here.

  • PBKDF2. While bcrypt and scrypt may be more secure than PBKDF2, CommonCryptor only supports PBKDF2. NIST also continues to recommend PBKDF2. We use 10k rounds of PBKDF2 which represents about 80ms on an iPhone 4.

Code simplicity

RNCryptor endeavors to be implemented as simply as possible, avoiding tricky code. It is designed to be easy to read and code review.

Performance

Performance is a goal, but not the most important goal. The code must be secure and easy to use. Within that, it is as fast and memory-efficient as possible.

Portability

Without sacrificing other goals, it is preferable to read the output format of RNCryptor on other platforms.

Version History

  • v2.2 Switches to file format v3 to deal with Issue #77.
  • v2.1 Switches to file format v2 to deal with Issue #44.
  • v2.0 adds asynchronous modes.
  • v2.1 backports RNCryptor to older versions of Mac OS X (and possibly iOS).

LICENSE

Except where otherwise indicated in the source code, this code is licensed under the MIT License:

Permission is hereby granted, free of charge, to any person obtaining a 
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
 
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

Portions of this code, indicated in the source, are licensed under the following license:

/*-
 * Copyright (c) 2008 Damien Bergamini <[email protected]>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

Portions of this code, indicated in the source, are licensed under the APSL license:

/*
 * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 *
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 *
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 *
 * @APPLE_LICENSE_HEADER_END@
 */

rncryptor-objc's People

Contributors

armenm avatar bassrock avatar carllindberg avatar csteynberg avatar danielvy avatar doradiology avatar gabceb avatar guysung avatar kaioelfke avatar klaaspieter avatar kvangork avatar madsolar8582 avatar mkhon avatar rnapier avatar slaunchaman avatar steipete avatar testzugang avatar timestretch avatar tyrone-sudeium avatar vphamdev avatar yeahphil avatar ykalchevskiy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rncryptor-objc's Issues

Synchronous methods hang on invalid key

Hey @rnapier,

I'm trying to refresh an old project by different developers who employed this library. However, it always seems to hang in the synchronousResultForCryptor:data:error: method. The semaphore there never seems to get signaled because the handler never seems to get called at all (i.e. https://github.com/RNCryptor/RNCryptor-objc/blob/master/RNCryptor/RNCryptor.m#L99-L122).

Am I missing some sort of dependency or configuration? I tried both with the old version originally in the project as well as the latest version here. I've spent several hours trying to figure this out and am really hoping you might have some ideas.

(For integration, I've tried the original grab-the-source-and-stick-it-in as well as Carthage. I noticed the Security framework is listed in the pod spec but assumed that would be automatically imported where a project generally needs it.)

Thanks in advance for your time in considering my little problem. 😄

P.S. I think I met you at a CocoaConf perhaps four or five years ago when you gave a talk on CoreText. I'm a native of Raleigh myself. 👍

How do I decrypt using a third party AES-CBC decryptor?

So far, I've been able to encrypt and decrypt nicely in iOS using this RNCryptor lib. But, the trouble comes when decryption needs to happen outside of the iOS playground. Here's what I've tried so far:

password
asdfasdfasdfasdf

plaintext
{ "stuff": "here" }

NSData *encryptedData = [RNEncryptor encryptData:[@"{ \"stuff\": \"here\" }" dataUsingEncoding:NSUTF8StringEncoding]
                                            withSettings:kRNCryptorAES256Settings
                                                password:@"asdfasdfasdfasdf"
                                                   error:&error];

Using password and plaintext in the RNCryptor-objc encryption library I get:
cipher hex
03 01 59 fe 9e 5f f2 c2 05 58 ab 85 29 c5 a5 6f ad 27 5e e0 e8 a1 af f2 1f e4 e9 61 8b 25 44 1b ba ee e4 71 ef 95 e9 16 3b 59 53 a2 74 d9 23 00 57 1f a6 4f b9 ff 86 8d e6 ae 76 5a 4a 15 eb b8 d0 b4 bb 54 50 d0 76 3d 45 1c b5 c3 41 1f 1d 09 b8 97 6a ba 91 44 2e 1f f4 54 42 44 ce 59 b0 cc 0b 14 64 30

Break up cipher hex into parts below according to this format (https://github.com/RNCryptor/RNCryptor-Spec/blob/master/RNCryptor-Spec-v3.md):
——————
version (1 byte)
03

options (1 byte)
01

encryption salt (8 bytes)
59 fe 9e 5f f2 c2 05 58

HMAC salt (8 bytes)
ab 85 29 c5 a5 6f ad 27

IV (16 bytes)
5e e0 e8 a1 af f2 1f e4 e9 61 8b 25 44 1b ba ee

ciphertext (x bytes)
e4 71 ef 95 e9 16 3b 59 53 a2 74 d9 23 00 57 1f a6 4f b9 ff 86 8d e6 ae 76 5a 4a 15 eb b8 d0 b4 bb 54

HMAC (32 bytes)
50 d0 76 3d 45 1c b5 c3 41 1f 1d 09 b8 97 6a ba 91 44 2e 1f f4 54 42 44 ce 59 b0 cc 0b 14 64 30

—————————

Using PBKDF2 function with 32 byte length, 10k iterations, SHA-1, and encryption salt (above), generate an encryption key (http://anandam.name/pbkdf2/):

encryption key
d57972b596a34a18e201d2f6a301424dcf269ccc757e07f91765935af491aa68

Then, decrypt to plaintext using ciphertext, IV, and encryption key using third party AES decryption function (http://extranet.cryptomathic.com/aescalc/index):
Decrypted plaintext in hex
AD409D9EFE09B360B2B905A82C41CE67BD7D106095742BFF055891F8CE1D524EAB6EDC147F565796ED7AAF6F4E8A024A

Convert from hex to ASCII:
Decrypted plaintext in ASCII
@ žþ ³²¹¨,AÎg½}•t+ÿX‘øÎRN«nÜ VW–íz¯oNŠJ


Obviously, I'm missing something here, but I'm not sure what it is. Am I missing padding on the cipher hex and/or HMAC and/or ciphertext? Am I not generating the encryption key correctly?

Thanks for any help you can provide,
Steve Y

Error compiling for arm64

The compiler tells me "Symbols not found for architecture arm64"

"OBJC_CLASS$_RNDecryptor", referenced from:
objc-class-ref
"OBJC_CLASS$_RNEncryptor", referenced from:
objc-class-ref
"_kRNCryptorAES256Settings", referenced from:

Carthage

How can this be used with Carthage for an Objective-C project?

RNCryptor error decrypting between IOS and PHP

0

I use the RNCrytpor in my IOS app to encrypt and when I try too decrypt in server side with PHP, sometimes that work and sometime not, I don't know why, I have no error information in PHP side.

This is my simple IOS code to encrypt (I try to encrypt the current Timestamp only for my test)

NSString *password = @"myPassword";
//ENCRYPT TEST

NSDate *date = [NSDate date];
NSTimeInterval ti = [date timeIntervalSince1970];
NSString *strTmSmp = [NSString stringWithFormat:@"%.0f",ti];


NSString *strKey = [NSString stringWithFormat:@"hello_%@",strTmSmp];

NSData *data = [strKey dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSData *encryptedData = [RNEncryptor encryptData:data
withSettings:kRNCryptorAES256Settings
  password:password
     error:&error];

NSString *keyValue = [encryptedData base64EncodedStringWithOptions:0];

NSDictionary *params = @{  @"key":  keyValue };

I use AfNetworking to POST my request

This is my simple PHP code to decrypt

$password = "myPassword";
$base64Encrypted = $_POST['key'];
$cryptor = new \RNCryptor\RNCryptor\Decryptor;
$plainText = @cryptor->decrypt($base64Encrypted,$password);
echo $plainText;

if someone can help me

Can I user like this

Can I use like this, I just need simple use and less params? But It is not work correct for me. The 'base64Encrypt' is not right.

const RNCryptorSettings kRNCryptorAES128Settings = {
    .algorithm = kCCAlgorithmAES128,
    .blockSize = kCCBlockSizeAES128,
    .IVSize = kCCBlockSizeAES128,
    .options = kCCOptionPKCS7Padding
};

    NSData *data = [@"Data" dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSData *encryptedData = [RNEncryptor encryptData:data
                                        withSettings:kRNCryptorAES128Settings
                                       encryptionKey:[@"15hcxttc3gas63st" dataUsingEncoding:NSUTF8StringEncoding]
                                             HMACKey:NULL
                                                  IV:[@"1234567890123456" dataUsingEncoding:NSUTF8StringEncoding]
                                               error:&error];
    
    NSString *base64Encrypt = [encryptedData base64EncodedStringWithOptions:0];

Security

We are using RNCryptor-objc library in our project for the purpose of encryption/decryption. While running static analyser tool for maintaining best security practices in our project, we have found one critical issue reported by the tool. Below is the issue:

Issue: "CBC mode is vulnerable to padding oracle attacks. CTR mode is the superior choice because it does not have these weaknesses."

As per the Description of RNCryptor-objc, the library used CBC mode.

So, I want to ask, is there any CTR mode version available for us to use. And if not, is there any possibility that you guys add it here in the library.

Also, there is a link placed in the library which says, "Mode changes for RNCryptor" but the link is not working.

Please let us know if you can help here and add the required mode which will be safer to use. Thanks!

'RNCryptor.h' file not found

I try to use RNCryptor in my app like so:

In my project:
Cartfile: github "RNCryptor/RNCryptor-objc"
carthage update RNCryptor-objc
Add framework to "General / Linked frameworks and libraries"

In a class file:
#import <RNCryptor/RNCryptor.h>

When trying to build:
While building module 'RNCryptor' imported from /Users/udo/Documents/Xcode-Projects/aktiv/Tresor/Shared/TSCryptoKeys.m:11: In file included from <module-includes>:1: In file included from /Users/udo/Documents/Xcode-Projects/aktiv/Tresor/Carthage/Build/iOS/RNCryptor.framework/Headers/RNCryptor iOS.h:22: /Users/udo/Documents/Xcode-Projects/aktiv/Tresor/Carthage/Build/iOS/RNCryptor.framework/PrivateHeaders/RNCryptorEngine.h:29:9: fatal error: 'RNCryptor.h' file not found #import "RNCryptor.h" ^ 1 error generated.

What am I doing wrong?

Decryption during download

Hello Rob,
Thank you very much for your effort in creating this brilliant library and spending time on maintaining it.
Could you please clarify the below question?
I have a bunch of audio files which are encrypted and stored in the server. The key is bundled with the client application.
Is it possible to use RNCryptor to decrypt the files during download, so that I can start playback before the file is completely downloaded?
I have gone through this discussion and as I understand, it is not supported, as of now.

Please share your thoughts on this.

The error "HMAC Mismatch" appears when I decrypt audio, sometimes it happens, not each time.

Hi,
I got a problem when I decrypted my encrypted audio file, after called '[decryptor isFinished]', the problem would appear. The error is "HMAC Mismatch", but I have no idea to solve it.

`- (void)encryptionDidFinish {
if (self.encryptor.error) {
//---> code often comes here!!! I can't get correct audio file. <---\
self.encryptedData = nil;
self.encryptor = nil;
}
else {
// self.encryptedData is complete. Use it as you like
[self writeEncryptedData];
if ([self.delegate respondsToSelector:@selector(onEncryptionDidFinish)]) {
[self.delegate onEncryptionDidFinish];
}
self.encryptedData = nil;
self.encryptor = nil;
}

}`

Support for SPM

How can I import this using SPM in a objc project? Seems like Package.swift file is missing

Decrypting File Encrypted with OpenSSL

Hi Rob.

Enjoying your encryption framework. But with the latest release it appears you have removed the RNOpenSSL encrypt and decrypt files.

I was unable to decrypt a file encrypted via terminal with OpenSSL. I tried the Basic Objective-C Usage in your documentation.

Is it still possible to use openssl with the latest RNCryptor version?

/Philip Borges

RNCryptor compatibility iOS 13

Hello there,

Is there anyone who managed to use RNCryptor on an iOS 13 device ? if so what's the compatible version ?

Need synchronous addData: and finish in the decrypt

I already replied with this in my issue asking about ObjC support in the Swift 5.0 RNCryptor, but the Swift one had decryption that happened synchronously. We need that in the ObjC version as well. I've temporarily done it in my local copy of the code but would defer to an appropriate implementation done in the style of the implementor.

Open encrypted file without decrypted local copy

Hi. @rnapier thank you for a job. I have a question. In my application I use UIWebVIew to view files (except images). UIWebVIew required data or link to the file. Data - not suitable for files can be quite large - so I can use NSOutputStream for decrypt - but in this case will need to create a local copy of the decrypted file (in a temp dir). Is there an alternative way, do not make copies of decrypted files?

ios11 beta error

In the ios11 beta version, will report the following error: Conflicting types for 'SecRandomCopyBytes'
How can i solve it?

Code Correctness

Hi
In the file RNEncryptor.m we have a security issue for code correctness.The snippet where issue is the method:
(NSData *)randomDataOfLength:(size_t)length
{
NSMutableData *data = [NSMutableData dataWithLength:length];

int result;
if (&SecRandomCopyBytes != NULL) {
result = SecRandomCopyBytes(NULL, length, data.mutableBytes);
}
Description: The issue is raised for &SecRandomCopyBytes i.e Because it is missing trailing parentheses, the expression on line 386 in RNCryptor.m refers to the value of a function pointer rather than the return value of the function.
Please suggest if the conecern is valid or not.

Memory spike problem and the fix

When encrypting/decrypting large files, in our case, the memory usage spikes to 1.5G and app quickly crashes. We found the problem to be caused by RNCryptorEngine:addData:error creating 48K NSData objects that are not released fast enough. The fix is pretty simple: to add @autoreleaseblock to the two functions that use RNCryptorEngine:addData:error:

RNEncryptor:

- (void)addData:(NSData *)data
{
    if (self.isFinished) {
        return;
    }
    
    dispatch_async(self.queue, ^{
        @autoreleasepool { // this fixes the memory issue
            if (!self.haveWrittenHeader) {
                NSData *header = [self header];
                [self.outData setData:header];
                if (self.hasHMAC) {
                    CCHmacUpdate(&self->_HMACContext, [header bytes], [header length]);
                }
                self.haveWrittenHeader = YES;
            }
            
            NSError *error = nil;
            NSData *encryptedData = [self.engine addData:data error:&error];
            if (!encryptedData) {
                [self cleanupAndNotifyWithError:error];
            }
            if (self.hasHMAC) {
                CCHmacUpdate(&self->_HMACContext, encryptedData.bytes, encryptedData.length);
            }
            
            [self.outData appendData:encryptedData];
            
            dispatch_sync(self.responseQueue, ^{
                self.handler(self, self.outData);
            });
            [self.outData setLength:0];
        }
    });
}

RNDecryptor:

- (void)decryptData:(NSData *)data
{
    dispatch_async(self.queue, ^{
        @autoreleasepool { // this fixes the memory issue
            if (self.hasHMAC) {
                CCHmacUpdate(&self->_HMACContext, data.bytes, data.length);
            }
            
            NSError *error = nil;
            NSData *decryptedData = [self.engine addData:data error:&error];
            
            if (!decryptedData) {
                [self cleanupAndNotifyWithError:error];
                return;
            }
            
            [self.outData appendData:decryptedData];
            
            dispatch_sync(self.responseQueue, ^{
                self.handler(self, self.outData);
            });
            [self.outData setLength:0];
        }
    });
}

Block implicitly retains 'self'

I am getting the above warning message in 6 places in the RNCryptor library. Full message is:

Pods/RNCryptor-objc/RNCryptor/RNDecryptor.m:169:21:
Block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior

Also found in:
RNDecryptor.m:312:20
RNEncryptor.m:202:23
RNEncryptor.m:213:21
RNEncryptor.m:236:21
RNEncryptor.m:238:20

Everything else with the library seems to be working great! (I'm just trying to get rid of all warnings in my project, whether from my code or not.)

Xcode 9 & iOS 11 beta issue

Hi ,
I have issue in RNCryptor.m file
RNCryptor.m:61:12: Conflicting types for 'SecRandomCopyBytes'
I am using pod 'RNCryptor-objc' .
My App is crashing becasue fo this issue .
Please let me know when do we have fix for this.

Thanks,
Venkat

Have you forgot to release 3.0.5

While writing at Podfile as pod 'RNCryptor-objc', '3.0.5', it gives error as below:

[!] Unable to satisfy the following requirements:

- `RNCryptor-objc (= 3.0.5)` required by `Podfile`

None of your spec sources contain a spec satisfying the dependency: `RNCryptor-objc (= 3.0.5)`.

You have either:
 * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
 * mistyped the name or version.
 * not added the source repo that hosts the Podspec to your Podfile.

Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.

If writing without version as pod 'RNCryptor-objc' , it installs 3.0.2

What is the corresponding openssl-algorithm for kRNCryptorAES256Settings?

I tried successfully your example code for working with streams. Using this library i can encrypt and decrypt files with the setting kRNCryptorAES256Settings.

But what setting is necessary to decrypt files, that were encrypted for instance with the "aes-256-cbc"-algorithm?

When i encrypt a file in the terminal with

openssl enc -aes-256-cbc -in m1010.jpg -out m1010.data

and decrypt this using RNDecryptor, the output is totally different and wrong.

Is there a list of corresponding settings available according to this library and those that are available in openssl? Thank you very much in advance

RNCryptor: encrypt in python and decrypt in Objc

Hi,

I use rncryptor for encryption in python

rncryptor.encrypt(data, password)

and decrypt it in Objc:

[RNDecryptor decryptData:encryptedData
                                                    withPassword:aPassword
                                                           error:&error];

but error return Unknown header

I have checked password both side, and try for decrypt with python and it's works.

Fortify security issue RNCryptor.m

Hi,

We are getting fortify security issue in function + (NSData *)randomDataOfLength:(size_t)length on below line
if (&SecRandomCopyBytes != NULL) {

Description :

This expression will always be non-null because it references a function pointer rather than the return value of the function.

Example 1: The following conditional will never fire. The predicate getChunk == NULL will always be false because getChunk is the name of a function defined in the program.

if (getChunk == NULL)
return ERR;

Thanks,
Usman

Use of banned api in library

I have run the penetrating security test on the iOS app found issue with RNEncryptor library.
pen test error : The binary may contain the following insecure API(s).

Following are the classes which used insecure api methods (memcpy)-

  • RNCryptor.m (Line number 242, 275, 279, 282)

Could you provide a solution for this?
Please suggest if you have any alternative for it.

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.