Giter Site home page Giter Site logo

rncryptor / rncryptor Goto Github PK

View Code? Open in Web Editor NEW
3.4K 119.0 516.0 1.87 MB

CCCryptor (AES encryption) wrappers for iOS and Mac in Swift. -- For ObjC, see RNCryptor/RNCryptor-objc

Home Page: https://groups.google.com/forum/#!forum/rncryptor

License: MIT License

Ruby 5.38% Swift 94.62%

rncryptor's Introduction

RNCryptor

BuddyBuild

Cross-language AES Encryptor/Decryptor data format.

The primary targets are Swift and Objective-C, but implementations are available in C, C++, C#, Erlang, Go, Haskell, Java, PHP, Python, Javascript, Ruby, and Dart.

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

Contents

Format Versus Implementation

The RNCryptor data format is cross-platform and there are many implementations. The framework named "RNCryptor" is a specific implementation for Swift and Objective-C. Both have version numbers. The current data format is v3. The current framework implementation (which reads the v3 format) is v4.

Basic Password Usage

// Encryption
let data: NSData = ...
let password = "Secret password"
let ciphertext = RNCryptor.encrypt(data: data, withPassword: password)

// Decryption
do {
    let originalData = try RNCryptor.decrypt(data: ciphertext, withPassword: password)
    // ...
} catch {
    print(error)
}

Incremental Usage

RNCryptor supports incremental use, for example when using with NSURLSession. This is also useful for cases where the encrypted or decrypted data will not comfortably fit in memory.

To operate in incremental mode, you create an Encryptor or Decryptor, call updateWithData() repeatedly, gathering its results, and then call finalData() and gather its result.

//
// Encryption
//
let password = "Secret password"
let encryptor = RNCryptor.Encryptor(password: password)
let ciphertext = NSMutableData()

// ... Each time data comes in, update the encryptor and accumulate some ciphertext ...
ciphertext.appendData(encryptor.updateWithData(data))

// ... When data is done, finish up ...
ciphertext.appendData(encryptor.finalData())

//
// Decryption
//
let password = "Secret password"
let decryptor = RNCryptor.Decryptor(password: password)
let plaintext = NSMutableData()

// ... Each time data comes in, update the decryptor and accumulate some plaintext ...
try plaintext.appendData(decryptor.updateWithData(data))

// ... When data is done, finish up ...
try plaintext.appendData(decryptor.finalData())

Importing into Swift

Most RNCryptor symbols are nested inside an RNCryptor namespace.

Installation

Requirements

RNCryptor 5 is written in Swift 3 and does not bridge to Objective-C (it includes features that are not available). If you want an ObjC implementation, see RNCryptor-objc. That version can be accessed from Swift, or both versions can coexist in the same project.

The Bridging Header

CommonCrypto is not a modular header (and Apple has suggested it may never be). This makes it very challenging to import into Swift. To work around this, the necessary header files have been copied into RNCryptor.h, which needs to be bridged into Swift. You can do this either by using RNCryptor as a framework, adding #import "RNCryptor/RNCryptor.h" to your existing bridging header, or making RNCryptor/RNCryptor.h your bridging header in Build Settings, "Objective-C Bridging Header."

Installing Manually

The easiest way to use RNCryptor is by making it part of your project, without a framework. RNCryptor is just one swift file and one bridging header, and you can skip all the complexity of managing frameworks this way. It also makes version control very simple if you use submodules, or checkin specific versions of RNCryptor to your repository.

This process works for most targets: iOS and OS X GUI apps, Swift frameworks, and OS X commandline apps. It is not safe for ObjC frameworks or frameworks that may be imported into ObjC, since it would cause duplicate symbols if some other framework includes RNCryptor.

  • Drag and link RNCryptor/RNCryptor.swift and RNCryptor.h into your project
  • If you already have a bridging header file, add #import "RNCryptor.h" (or the path to which you copied RNCryptor.h).
  • If you don't have a bridging header:
    • Swift project: In your target's Build Settings, set "Objective-C Bridging Header" to your path for RNCryptor.h. (Or create a bridiging header and follow instructions above.)
    • ObjC project: Xcode will ask if you want to create a bridging header. Allow it to, and add #import "RNCryptor.h" to the header (or the path to which you copied RNCryptor.h)
  • To access RNCryptor from Swift, you don't need to import anything. It's just part of your module.
  • To access RNCryptor from ObjC, import your Swift header (modulename-Swift.h). For example: #import "MyApp-Swift.h".

Built this way, you don't need to (and can't) import RNCryptor into your code. RNCryptor will be part of your module.

github "RNCryptor/RNCryptor" ~> 5.0

This approach will not work for OS X commandline apps. Don't forget to embed RNCryptor.framework.

Built this way, you should add @import RNCryptor; to your ObjC or import RNCryptor to your Swift code.

This approach will not work for OS X commandline apps.

pod 'RNCryptor', '~> 5.0'

This approach will not work for OS X commandline apps.

Built this way, you should add import RNCryptor to your Swift code.

dependencies: [
    .package(url: "https://github.com/RNCryptor/RNCryptor.git", .upToNextMajor(from: "5.0.0"))
]

Swift Package Manager support requires Xcode 12.5 or higher.

Built this way, you should add import RNCryptor to your Swift code.

Advanced Usage

Version-Specific Cryptors

The default RNCryptor.Encryptor is the "current" version of the data format (currently v3). If you're interoperating with other implementations, you may need to choose a specific format for compatibility.

To create a version-locked cryptor, use RNCryptor.EncryptorV3 and RNCryptor.DecryptorV3.

Remember: the version specified here is the format version, not the implementation version. The v4 RNCryptor framework reads and writes the v3 RNCryptor data format.

Key-Based Encryption

You need a little expertise to use key-based encryption correctly, and it is very easy to make insecure systems that look secure. The most important rule is that keys must be random across all their bytes. If you're not comfortable with basic cryptographic concepts like AES-CBC, IV, and HMAC, you probably should avoid using key-based encryption.

Cryptography works with keys, which are random byte sequences of a specific length. The RNCryptor v3 format uses two 256-bit (32-byte) keys to perform encryption and authentication.

Passwords are not "random byte sequences of a specific length." They're not random at all, and they can be a wide variety of lengths, very seldom exactly 32. RNCryptor defines a specific and secure way to convert passwords into keys, and that is one of it's primary features.

Occasionally there are reasons to work directly with random keys. Converting a password into a key is intentionally slow (tens of milliseconds). Password-encrypted messages are also a 16 bytes longer than key-encrypted messages. If your system encrypts and decrypts many short messages, this can be a significant performance impact, particularly on a server.

RNCryptor supports direct key-based encryption and decryption. The size and number of keys may change between format versions, so key-based cryptors are version-specific.

In order to be secure, the keys must be a random sequence of bytes. See Converting a Password to a Key for how to create random sequences of bytes if you only have a password.

let encryptor = RNCryptor.EncryptorV3(encryptionKey: encryptKey, hmacKey: hmacKey)
let decryptor = RNCryptor.DecryptorV3(encryptionKey: encryptKey, hmacKey: hmacKey)

FAQ

How do I detect an incorrect password?

If you decrypt with the wrong password, you will receive an HMACMismatch error. This is the same error you will receive if your ciphertext is corrupted.

The v3 data format has no way to detect incorrect passwords directly. It just decrypts gibberish, and then uses the HMAC (a kind of encrypted hash) to determine that the result is corrupt. You won't discover this until the entire message has been decrypted (during the call to finalData()).

This can be inconvenient for the user if they have entered the wrong password to decrypt a very large file. If you have this situation, the recommendation is to encrypt some small, known piece of data with the same password. Test the password on the small ciphertext before decrypting the larger one.

The v4 data format will provide a faster and more useful mechanism for validating the password or key.

What is an "HMAC Error?" (Error code 1)

See previous question. Either your data is corrupted or you have the wrong password.

The most common cause of this error (if your password is correct) is that you have misunderstood how Base64 encoding works while transferring data to or from the server. If you have a string like "YXR0YWNrIGF0IGRhd24=", this is not "data." This is a string. It is probably Base64 encoded, which is a mechanism for converting data into strings. Some languages (JavaScript, PHP) have a habit of implicitly converting between data into Base64 strings, which is confusing and error-prone (and the source of many of these issues). Simple rule: if you can print it out without your terminal going crazy, it's not encrypted data.

If you convert a Base64-encoded string to data using dataUsingEncoding(), you will get gibberish as far as RNCryptor is concerned. You need to use init?(base64EncodedData:options:). Depending on the options on the iOS side or the server side, spaces and newlines may matter. You need to verify that precisely the bytes that came out of the encryptor are the bytes that go into the decryptor.

Can I use RNCryptor to read and write my non-RNCryptor data format?

No. RNCryptor implements a specific data format. It is not a general-purpose encryption library. If you have created your own data format, you will need to write specific code to deal with whatever you created. Please make sure the data format you've invented is secure. (This is much harder than it sounds.)

If you're using the OpenSSL encryption format, see RNOpenSSLCryptor.

Can I change the parameters used (algorithm, iterations, etc)?

No. See previous question. The v4 format will permit some control over PBKDF2 iterations, but the only thing configurable in the v3 format is whether a password or key is used. This keeps RNCryptor implementations dramatically simpler and interoperable.

How do I manually set the IV?

You don't. See the last two questions.

Also note that if you ever reuse a key+IV combination, you risk attackers decrypting the beginning of your message. A static IV makes a key+IV reuse much more likely (guarenteed if you also have a static key). Wikipedia has a quick overview of this problem.

How do I encrypt/decrypt a string?

AES encrypts bytes. It does not encrypt characters, letters, words, pictures, videos, cats, or ennui. It encrypts bytes. You need to convert other things (such as strings) to and from bytes in a consistent way. There are several ways to do that. Some of the most popular are UTF-8 encoding, Base-64 encoding, and Hex encoding. There are many other options. There is no good way for RNCryptor to guess which encoding you want, so it doesn't try. It accepts and returns bytes in the form of NSData.

To convert strings to data as UTF-8, use dataUsingEncoding() and init(data:encoding:). To convert strings to data as Base-64, use init(base64EncodedString:options:) and base64EncodedStringWithOptions().

Does RNCryptor support random access decryption?

The usual use case for this is encrypting media files like video. RNCryptor uses CBC encryption, which prevents easy random-access. While other modes are better for random-access (CTR for instance), they are more complicated to implement correctly and CommonCrypto doesn't support using them for random access anyway.

It would be fairly easy to build a wrapper around RNCryptor that allowed random-access to blocks of some fixed size (say 64k), and that might work well for video with modest overhead (see inferno for a similar idea in C#). Such a format would be fairly easy to port to other platforms that already support RNCryptor.

If there is interest, I may eventually build this as a separate framework.

See also Issue #161 for a much longer discussion of this topic.

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+SHA256, and PBKDF2. (Note that several of these decisions were reasonable for v3, but may change for v4.)

  • 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-then-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.

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. ```

rncryptor's People

Contributors

ale-gen avatar an0 avatar armenm avatar bassrock avatar carllindberg avatar chkpnt avatar csteynberg avatar danielvy avatar dlo avatar gabceb avatar guysung avatar ianrahman avatar klaaspieter avatar kvangork avatar madsolar8582 avatar orthographic-pedant avatar rnapier avatar schnippi avatar slaunchaman avatar steipete avatar testzugang avatar timestretch avatar tyrone-sudeium avatar tzraikov avatar verticon 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  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

rncryptor's Issues

Encrypt in PHP & Decrypt in iOS

I have to Encrypt in PHP & Decrypt in iOS and below is my code

PHP

$key = 'mykey';
$data = "iphone";
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$pad = $block - (strlen($data) % $block);
$data .= str_repeat(chr($pad), $pad);

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

$keySalt = '12345678';
$hmacSalt = '12345678';

$_key = pbkdf2('SHA1', $key, $keySalt, 10000, 32, true);
$_hmacKey = pbkdf2('SHA1', $key, $hmacSalt, 10000, 32, true);

$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $_key, $data, MCRYPT_MODE_CBC, $iv);

$data = base64_encode(chr(1).chr(0).$keySalt.$hmacSalt.$iv.$ciphertext.hash_hmac('SHA256',$ciphertext,$_hmacKey, true));

echo $data;

after that I copied the $data from my browser and pasted in the iOS code which is like the following:

    decryptionError = nil;
    NSData *fromPHPData = [[@"AQAxMjM0NTY3ODEyMzQ1Njc4cgfFQGBMsSsfQPjrItNeHSzvvZq+6X0WPrks5pRKOzEQJXS02ltnZtdvFloxqZ20Saqqu/yLrZmymDRMtryyH4pFg+PSGxGUtwynKotSa5Dg3nv56k9a4tRaUXJzkZuo" base64DecodedString] dataUsingEncoding:NSUTF8StringEncoding];
    NSData *fromPHPDecryptedData = [RNDecryptor decryptData:fromPHPData withPassword:@"mykey" error:&decryptionError];
    NSLog(@"decryptionError %@", decryptionError);
    NSString *fromPHPEcryptedStr = [[NSString alloc] initWithData:fromPHPDecryptedData encoding:NSUTF8StringEncoding];
    NSLog(@"data : %@", fromPHPEcryptedStr);

and my iOS output is like the follwoing
decryptionError (null)
data :

Can any one help me in this issue

Decrypt in PHP

I am using RNCryptor to encrypt data in iOS (client side), and would like to decrypt the encrypted data in PHP (server side). Below is my PHP code, but it failed to extract the correct data. I think it's due to the RNCryptor has its own output format. Is it possible to manage the PHP code to decrypt the RNCryptor output?

function aes256Decrypt($key, $data) {
if(32 !== strlen($key)) $key = hash('SHA256', $key, true);
$data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, str_repeat("\0", 16));
$padding = ord($data[strlen($data) - 1]);
$result = substr($data, 0, -$padding);
return substr($data, 0, -$padding);
}

NSString out of encrypted NSData object?

How to get the ecrypted string out of the NSData object?

I tried with this:

NSData *encr = [[RNCryptor AES256Cryptor] encryptData:plain password:key error:&error];
NSString *encrString = [[NSString alloc] initWithData:encr encoding:NSUTF8StringEncoding];

but the output says that its not a CFString.

Please help.

Application Crash

Running XCode 4.5.1

Application crashes on start with the following error:
libobjc.A.dylib`objc_msgSend:

Tested on both ios 5.1.1, and ios 6. error message differs on ios 6:
libobjc.A.dylib`objc_retain:

Switch to CMS/PKCS#7 format?

Adds significant complexity (potential bugs) for ASN.1 parsing, but could dramatically improve interoperability. Would be nice to avoid "yet another data format."

RFC 5652
RFC 6476

Primary concern is that complexity and open-ended flexibility breed bugs. The current parser is extremely simple. An ASN.1 parser is not.

encrypt.php example for AES128

Hi, rnapier,
I want to use your encrypt.php example for AES128.
Do you have an example code for AES128? or Does RNCryptor only support AES256?
FYI, I am using RNCryptor1.1.
Thanks.

How to use CCKeyDerivationPBKDF on iOS4

Which piece do you need? Just CCKeyDerivationPBKDF? Have you tried just using CommonKeyDerivation.c? If it causes much trouble, open an issue on RNCryptor with what you're trying to achieve on iOS4 and I'll see what I can do. https://github.com/rnapier/RNCryptor

Rob, Since CCKeyDerivationPBKDF is not available until after iOS 5.0, people have suggested using the open source code for CommonCrypto available here:

http://www.opensource.apple.com/source/CommonCrypto/CommonCrypto-55010/

I think we cannot simply compile CommonKeyDerivation.c because it requires a few other functions. Can you help with what and how to compile appropriate files in an Xcode project which also needs to work with iOS4 devices? I can also pay a reasonable consulting fees for help with this - just let me know.

Fails on iOS 6 beta 1, kCCModeCTR unsupported

The stock AES256Cryptor fails to be created on iOS 6 beta 1 because it doesn't seem to support kCCModeCTR. This was supported properly on iOS 5.

Other modes, such as kCCModeCFB, appear to work perfectly well.

I've filed a bug with Apple on this, rdar 11714286. But it might not get fixed in time for iOS 6's release. And it might be intentional — maybe kCCModeCTR will be gone permanently in iOS 6. It's probably worth investigating different default settings if this isn't resolved within the next two iOS 6 betas.

kSecRandomDefault not available on OS X

RNCryptor uses the kSecRandomDefault constant which is not available under OS X. This prevents RNCryptor from compiling unter OS X. You could use NULL instead of kSecRandomDefault - I think. At least the documentation says:

This constant is a synonym for NULL.

Decryption not compatible with older version's encryption

Hi,

I upgraded to the latest version, and it doesn't seem to be able to decrypt data encrypted by an older version. Could you advise? Thanks!

The decryption failed here:

RNDecryptor.m Line 142

139 - (BOOL)getSettings:(RNCryptorSettings *)settings forPreamble:(NSData *)preamble 140 { 141 const uint8_t *bytes = [preamble bytes]; 142 if (bytes[0] == kRNCryptorFileVersion) { // Failed here, kRNCryptorFileVersion is 1, but the encrypted data has a header of "00" (first 2 bytes). 143 *settings = kRNCryptorAES256Settings;

Retreive IV

Hi all,

How I can get the IV to send to the server and to decrypt the message?

I use Python + Tornado on the server, would it be possible to take the IV directly on the server?

Thank you!

add data to the end of crypted file.

I'm using RNCryptor to encrypt/decrypt files in ios and mac app, i want to 'sign' my file with a string so i can know if its my crypted file or not.
methodologie :
*encryption:
1-crypt file.
2-add my string as data to the crypted data.
*decryption:
1-get the range of the string and remove it from crypted data.
2-decrypt the data.

but when i decrypt file, ihave this error "Error Domain=net.robnapier.RNCryptManager Code=-4301 "L’opération n’a pas pu s’achever. (net.robnapier.RNCryptManager erreur -4301)."

I'm pretty sur that sign/unsign work because i sign an image and when i unsign it i have a good result.

code:


     NSMutableData *originalData = [NSMutableData dataWithContentsOfFile:[file.filePath stringByReplacingOccurrencesOfString:@"file://localhost" withString:@""]];
NSMutableData *cryptedData= [NSMutableData dataWithData:[RNEncryptor encryptData:originalData withSettings:kRNCryptorAES256Settings password:textFieldPassWordForEncryption.stringValue error:&error]];
NSMutableData *signedData = [self signFileData:cryptedData];
NSMutableData *unsigneddata = [self removeSigntureInRange:[self testIntegrityFromData:signedData] FromData:signedData];
NSMutableData *decryptedData = [NSMutableData dataWithData:[RNDecryptor decryptData:unsigneddata withPassword:textFieldPassWordForDecryption.stringValue error:&error]];
NSLog([error description]);
[imageTest setImage:[[NSImage alloc]initWithData:decryptedData]];

     -(NSMutableData*) signFileData:(NSMutableData*) fileData
   {
   NSData *signData = [signture dataUsingEncoding:NSASCIIStringEncoding];
   [fileData appendData:signData];
    return fileData;
   }

     -(NSRange) testIntegrityFromData:(NSMutableData*)fileData
  {    
  NSData* dataToFind = [signture dataUsingEncoding:NSASCIIStringEncoding];
  NSRange range = [fileData rangeOfData: dataToFind options:0 range:NSMakeRange(0, [fileData    length])];

if (range.length > 0)
{
    return range;
}
else
{
    return range;
}
 }

       -(NSMutableData*) removeSigntureInRange:(NSRange)range FromData:    (NSMutableData*)dataFile
     {
      NSMutableData *d = [NSMutableData dataWithData:[dataFile subdataWithRange:NSMakeRange(0, range.location+1)]];
     return d;
      }

Usage of SHA-2 for PBKDF2?

I know that it might not be a security issue, but I've noticed that in the default RNCryptorSettings kRNCryptorAES256Settings SHA1 is used as PRF for PBKDF2.

But as there are no performance differences, I'd recommend to use SHA-2 (e.g. SHA-256) for the key generation. What do you think?

Crash when reading v1 header

When attempting to decrypt a file stored with a v1 header (or possibly any bad header), the application crashes on line 116 (https://github.com/rnapier/RNCryptor/blob/8b01b2bf89ee9773ed863af4204bc808e0e9a831/RNCryptor/RNDecryptor.m#L116) in RNDecryptor with a EXC_BAD_ACCESS.

Looking at the code, it seemed to me there was a return statement missing in consumeHeaderFromData after the call to cleanupAndNotifyWithError at https://github.com/rnapier/RNCryptor/blob/8b01b2bf89ee9773ed863af4204bc808e0e9a831/RNCryptor/RNDecryptor.m#L172. Inserting a return there seemed to stop the application from crashing, but I'm not sure if this is the root problem or the correct fix.

Encrypt and Decrypt in Python

Hello.
I am encrypting some data in iOS and then sending it to Python server. My python server is returning some garbage data. And then I want to encode reply and send it back to iOS. I am using:
def encrypt(auth_info):
if auth_info is None:
return None
iv = Random.new().read(AES.block_size)
cipher = AES.new(key[:32], AES.MODE_CFB, iv)
res = base64.b64encode(iv + cipher.encrypt(auth_info))
return res

def decrypt(auth_info):
if auth_info is None:
return None
auth = base64.b64decode(auth_info)
iv = auth[:AES.block_size]
cipher = AES.new(key[:32], AES.MODE_CFB, iv)
res = cipher.decrypt(auth[AES.block_size:])
return res

Can you help me? Thank you.

Usage of custom RNCryptorSettings?

For encryption it's possible to use custom RNCryptorSettings (which are defined e.g. in a RNCryptor Category):

NSData *encryptedData = [RNEncryptor encryptData:myData withSettings:kRNCryptorMySettings password:myPassword error:&error];

It seems like the decryption functionality always uses kRNCryptorAES256Settings when the first byte of the encrypted data matches the RNCryptor version number. It would be a great feature if you could use your custom RNCryptorSettings for encryption and decryption. Maybe this could be realized with an identifier (like kRNCryptorFileVersion) in the RNCryptorSettings that overrides the kRNCryptorFileVersion if set and will be written into the first byte?

dispatch_get_current_queue() is deprecated in iOS 6+

Hi,

dispatch_get_current_queue() is deprecated in iOS 6+ as it is stated in usr/include/dispatch/queue.h for iOS6

  • This function is deprecated and will be removed in a future release.
    *
  • @Result
  • Returns the current queue.
    */
    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6,__MAC_NA,__IPHONE_4_0,__IPHONE_6_0)
    DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW
    dispatch_queue_t
    dispatch_get_current_queue(void);

It is used in initWithHandler: inside a RNCryptor.m.

Maybe RNCryptor should create it's own queue with dispatch_create in order for code to be future-proof and get rid of compiler warning?

Investigate decrypt settings

Currently RNDecryptor doesn't have any settings by default. You'd think that it wouldn't decrypt properly that way. Need to double-check why this is working, and if there's an issue.

Encrypt in iOS and decrypt in PHP

Hello.
How can I decrypt encrypted string in php? I see your example of encrypting, can you give me example of decrypting please?
Thank you.

OpenSSL encryption and decryption

I'm trying to encrypt and then decrypt a .zip with the following methods https://gist.github.com/4706999, which are called in nested completion blocks. At the end I should have the original file, if my logic doesn't fail me, yet somehow the final file is a corrupted .zip.

Is the encryption the equivalent of
"openssl enc -aes-256-cbc -in in_unenc.zip -k 1234 -p -out out.zip"
?

Seems like a subtle bug somewhere, but I can't put my finger on it.

Xcode warn using garbage value.

in [RNDecryptor consumeHeaderFromData:]
If [self getSettings:forPreamble:] failed, the value 'settings' leave uninitialized.

NSUInteger headerSize = kPreambleSize + settings.IVSize;

is this correct?

OpenSSL with salt

Apologies if this issue is just a misunderstanding of the protocol, but when using the RNOpenSSLEncryptor and initialising it with a key and IV, although there's no salt value created as part of the password to key generation, a header with a salt is still added as

  • (NSData *)header

always prepends the header and salt.

However, is this needed if the a key/iv are provided instead of a password? Files I encrypt using other SSL libraries (such as in Ruby) don't add a SALTED header.

Similarly, for RNOpenSSLDecryptor if I initialise it with a key and IV, then

  • (RNDecryptor *)initWithSettings:(RNCryptorSettings)theSettings encryptionKey:(NSData *)anEncryptionKey IV:(NSData *)anIV handler:(RNCryptorHandler)aHandler

sets a value for engine

self.engine = ....

which means consumeHeaderFromData isn't called, and so the header is read instead as part of the data.

If I change the header generator in the encryptor by wrapping it in a conditional:

if (self.encryptionSalt) {

and returning nil otherwise, everything works perfectly.

Is this a misuse of the class, or is my fix correct?

Asynchronously decrypt a large file

I need to asynchronously decrypt a large file on iOS (so as to show a progress bar). I have found no example anywhere, and thus have tried what I guessed was right, but... what I've come up with doesn't work :

NSOutputStream *decryptedStream = [NSOutputStream outputStreamToFileAtPath:decryptedPath append:NO];
[decryptedStream open];

NSUInteger totalBytesToRead = [[[NSFileManager defaultManager] attributesOfItemAtPath:tempPath error:nil] fileSize];
__block NSUInteger totalBytesRead = 0;

LOG("I've got %d bytes to decrypt.", totalBytesToRead);

RNDecryptor *decryptor = [[RNDecryptor alloc] initWithPassword:SNCatalogPassword handler:^(RNCryptor *cryptor, NSData *data) {
    totalBytesRead += data.length;
    [decryptedStream write:data.bytes maxLength:data.length];

    LOG("Decrypted %d bytes : %d / %d bytes treated", data.length, totalBytesRead, totalBytesToRead);

    if (cryptor.isFinished)
    {
        //proceed
        LOG("Done with decrypting.");

        [decryptedStream close];

    }
}];

// Feed data to the decryptor
NSInputStream *cryptedStream = [NSInputStream inputStreamWithFileAtPath:tempPath];
[cryptedStream open];
while (cryptedStream.hasBytesAvailable)
{
    uint8_t buf[4096];
    NSUInteger bytesRead = [cryptedStream read:buf maxLength:4096];
    NSData *data = [NSData dataWithBytes:buf length:bytesRead];
    LOG("Sending %d bytes to decryptor...", bytesRead);

    dispatch_async(dispatch_get_main_queue(), ^{
        [decryptor addData:data];
    });
}

LOG("Sent everything.");
[decryptor finish];
[cryptedStream close];

(Obvsiouly, tempPath is the path to the crypted file ; decryptedPath is the path where decrypted data should be written).

Thanks for any help.

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.